ZQuest Classic Coverage Report


Directory: src/
File: src/zc/maps.cpp
Date: 2025-08-01 10:38:16
Exec Total Coverage
Lines: 4078 5027 81.1%
Functions: 292 329 88.8%
Branches: 3153 5069 62.2%

Line Branch Exec Source
1 #include "base/combo.h"
2 #include "base/handles.h"
3 #include "base/util.h"
4 #include "base/zdefs.h"
5 #include "base/general.h"
6 #include <cstring>
7 #include <assert.h>
8 #include <math.h>
9 #include <vector>
10 #include <deque>
11 #include <string>
12 #include <set>
13 #include <array>
14 #include <sstream>
15 using std::set;
16
17 #include "base/qrs.h"
18 #include "base/dmap.h"
19 #include "base/mapscr.h"
20 #include "base/misctypes.h"
21 #include "base/initdata.h"
22 #include "zc/maps.h"
23 #include "zc/zelda.h"
24 #include "zc/zc_ffc.h"
25 #include "tiles.h"
26 #include "sprite.h"
27 #include "gui/jwin.h"
28 #include "base/zsys.h"
29 #include "subscr.h"
30 #include "zc/zc_subscr.h"
31 #include "zc/hero.h"
32 #include "zc/guys.h"
33 #include "zc/ffscript.h"
34 #include "drawing.h"
35 #include "zc/combos.h"
36 #include "zc/replay.h"
37 #include "slopes.h"
38 #include "particles.h"
39 #include <fmt/format.h>
40 #include "zc/render.h"
41 #include "iter.h"
42 #include <ranges>
43
44 // All the temporary screens (and their layers) for the currently loaded map.
45 static mapscr* temporary_screens[136*7];
46 // Set by load_region.
47 static bool screen_in_current_region[136];
48 416 static rpos_handle_t current_region_rpos_handles[136*7];
49 static bool current_region_rpos_handles_dirty;
50 static int current_region_screen_count;
51 static std::pair<const rpos_handle_t*, int> current_region_rpos_handles_scr[136];
52
53 viewport_t viewport;
54 static int viewport_sprite_uid;
55 ViewportMode viewport_mode;
56 int world_w, world_h;
57 int region_scr_dx, region_scr_dy;
58 int region_scr_count;
59 rpos_t region_max_rpos;
60 int region_num_rpos;
61 region_t cur_region, scrolling_region;
62
63 416 maze_state_t maze_state;
64 int scrolling_maze_last_solved_screen;
65
66 581 void maps_init_game_vars()
67 {
68 581 viewport = {};
69 581 viewport_mode = ViewportMode::CenterAndBound;
70 581 viewport_sprite_uid = 1;
71 581 currscr_for_passive_subscr = -1;
72 581 }
73
74 static region_ids_t current_region_ids;
75
76 14616183 static bool is_a_region(int map, int scr)
77 {
78 14616183 return get_region_id(map, scr) != 0;
79 }
80
81 2232 static bool is_same_region_id(int region_origin_scr, int map, int scr)
82 {
83
2/2
✓ Branch 0 taken 772 times.
✓ Branch 1 taken 1460 times.
2232 if (!is_a_region(map, scr)) return false;
84 1460 int region_id = get_region_id(map, region_origin_scr);
85
1/2
✓ Branch 0 taken 1460 times.
✗ Branch 1 not taken.
1460 return region_id && region_id == get_region_id(map, scr);
86 2232 }
87
88 137747680 bool is_in_current_region(int map, int screen)
89 {
90
5/6
✓ Branch 0 taken 137746107 times.
✓ Branch 1 taken 1573 times.
✓ Branch 2 taken 137746107 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12213 times.
✓ Branch 5 taken 137733894 times.
137747680 return map == cur_map && screen >= 0 && screen < 128 && screen_in_current_region[screen];
91 }
92
93 69622371 bool is_in_current_region(int screen)
94 {
95
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 69622370 times.
69622371 return screen < 128 && screen_in_current_region[screen];
96 }
97
98 28995047 bool is_in_current_region(mapscr* scr)
99 {
100
4/4
✓ Branch 0 taken 28980026 times.
✓ Branch 1 taken 15021 times.
✓ Branch 2 taken 462663 times.
✓ Branch 3 taken 28517363 times.
28995047 return scr->map == cur_map && scr->screen < 128 && screen_in_current_region[scr->screen];
101 }
102
103 bool is_in_scrolling_region(int screen)
104 {
105 if (!screenscrolling) return false;
106
107 int x = screen % 16;
108 int y = screen / 16;
109 return
110 scrolling_region.origin_screen_x >= x && scrolling_region.origin_screen_x < x + scrolling_region.screen_width &&
111 scrolling_region.origin_screen_y >= y && scrolling_region.origin_screen_y < y + scrolling_region.screen_height;
112 }
113
114 9026042054 bool is_in_scrolling_region()
115 {
116 9026042054 return cur_region.screen_count > 1;
117 }
118
119 76828944 bool is_extended_height_mode()
120 {
121
2/2
✓ Branch 0 taken 76578810 times.
✓ Branch 1 taken 250134 times.
76828944 return cur_region.screen_height > 1 && (DMaps[cur_dmap].flags & dmfEXTENDEDVIEWPORT);
122 }
123
124 // Returns 0 if this is not a region.
125 15658225 int get_region_id(int map, int screen)
126 {
127
2/2
✓ Branch 0 taken 401435 times.
✓ Branch 1 taken 15256790 times.
15658225 if (screen >= 128) return 0;
128
2/2
✓ Branch 0 taken 15255690 times.
✓ Branch 1 taken 1100 times.
15256790 if (map == cur_region.map) return current_region_ids[screen];
129
130 1100 return Regions[map].get_region_id(screen);
131 15658225 }
132
133 982758 int get_current_region_id()
134 {
135 982758 return get_region_id(cur_map, cur_screen);
136 }
137
138 64221 void calculate_region(int map, int screen, region_t& region, int& region_scr_dx, int& region_scr_dy)
139 {
140 64221 region.map = map;
141
142
3/4
✓ Branch 0 taken 274 times.
✓ Branch 1 taken 63947 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 274 times.
64221 if (!(is_a_region(map, screen)) || screen >= 0x80)
143 {
144 63947 region.region_id = 0;
145 63947 region.origin_screen = screen;
146 63947 region.origin_screen_x = screen % 16;
147 63947 region.origin_screen_y = screen / 16;
148 63947 region.screen_width = 1;
149 63947 region.screen_height = 1;
150 63947 region.screen_count = 1;
151 63947 region.width = 256;
152 63947 region.height = 176;
153 63947 region_scr_dx = 0;
154 63947 region_scr_dy = 0;
155 63947 return;
156 }
157
158 274 int input_scr_x = screen % 16;
159 274 int input_scr_y = screen / 16;
160
161 // For the given screen, find the top-left corner of its region.
162 274 int origin_scr_x = input_scr_x;
163 274 int origin_scr_y = input_scr_y;
164 274 int origin_scr = screen;
165
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 372 times.
434 while (origin_scr_x > 0)
166 {
167
2/2
✓ Branch 0 taken 212 times.
✓ Branch 1 taken 160 times.
372 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x - 1, origin_scr_y))) break;
168 160 origin_scr_x--;
169 }
170
2/2
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 414 times.
508 while (origin_scr_y > 0)
171 {
172
2/2
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 234 times.
414 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, origin_scr_y - 1))) break;
173 234 origin_scr_y--;
174 }
175 274 origin_scr = map_scr_xy_to_index(origin_scr_x, origin_scr_y);
176
177 // Now find the bottom-right corner.
178 274 int region_scr_right = origin_scr_x;
179
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 614 times.
642 while (region_scr_right < 15)
180 {
181
2/2
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 368 times.
614 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(region_scr_right + 1, origin_scr_y))) break;
182 368 region_scr_right++;
183 }
184 274 int region_scr_bottom = origin_scr_y;
185
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 832 times.
856 while (region_scr_bottom < 7)
186 {
187
2/2
✓ Branch 0 taken 250 times.
✓ Branch 1 taken 582 times.
832 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, region_scr_bottom + 1))) break;
188 582 region_scr_bottom++;
189 }
190
191 274 region.region_id = get_region_id(map, origin_scr);
192 274 region.origin_screen = origin_scr;
193 274 region.origin_screen_x = origin_scr_x;
194 274 region.origin_screen_y = origin_scr_y;
195 274 region.screen_width = region_scr_right - origin_scr_x + 1;
196 274 region.screen_height = region_scr_bottom - origin_scr_y + 1;
197 274 region.screen_count = region.screen_width * region.screen_height;
198 274 region.width = 256 * region.screen_width;
199 274 region.height = 176 * region.screen_height;
200 274 region_scr_dx = input_scr_x - origin_scr_x;
201 274 region_scr_dy = input_scr_y - origin_scr_y;
202
203 DCHECK_RANGE_INCLUSIVE(region.screen_width, 0, 16);
204 DCHECK_RANGE_INCLUSIVE(region.screen_height, 0, 8);
205 64221 }
206
207 35860 void load_region(int dmap, int screen)
208 {
209 35860 clear_temporary_screens();
210
211 35860 int map = DMaps[dmap].map;
212 35860 current_region_ids = Regions[map].get_all_region_ids();
213
214 35860 calculate_region(map, screen, cur_region, region_scr_dx, region_scr_dy);
215 35860 cur_screen = cur_region.origin_screen;
216 35860 world_w = cur_region.width;
217 35860 world_h = cur_region.height;
218 35860 region_scr_count = cur_region.screen_count;
219 35860 region_max_rpos = (rpos_t)(cur_region.screen_count*176 - 1);
220 35860 region_num_rpos = cur_region.screen_count*176;
221 35860 scrolling_maze_last_solved_screen = 0;
222
223 35860 memset(screen_in_current_region, false, sizeof(screen_in_current_region));
224
2/2
✓ Branch 0 taken 36094 times.
✓ Branch 1 taken 35860 times.
71954 for (int x = 0; x < cur_region.screen_width; x++)
225 {
226
2/2
✓ Branch 0 taken 37104 times.
✓ Branch 1 taken 36094 times.
73198 for (int y = 0; y < cur_region.screen_height; y++)
227 {
228 37104 int screen = cur_screen + x + y*16;
229
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37104 times.
37104 if (screen < 136)
230 {
231 37104 screen_in_current_region[screen] = true;
232 37104 }
233 37104 }
234 36094 }
235
236 35860 mark_current_region_handles_dirty();
237 35860 }
238
239 35860 static void prepare_current_region_handles()
240 {
241 35860 current_region_rpos_handles_dirty = false;
242 35860 current_region_screen_count = 0;
243
2/2
✓ Branch 0 taken 36208 times.
✓ Branch 1 taken 35860 times.
72068 for (int y = 0; y < cur_region.screen_height; y++)
244 {
245
2/2
✓ Branch 0 taken 37104 times.
✓ Branch 1 taken 36208 times.
73312 for (int x = 0; x < cur_region.screen_width; x++)
246 {
247 37104 int screen = cur_screen + x + y*16;
248 37104 int index_start = current_region_screen_count;
249
2/2
✓ Branch 0 taken 37104 times.
✓ Branch 1 taken 259728 times.
296832 for (int layer = 0; layer <= 6; layer++)
250 {
251 259728 mapscr* scr = get_scr_layer(screen, layer);
252
2/2
✓ Branch 0 taken 84565 times.
✓ Branch 1 taken 175163 times.
259728 if (!scr->is_valid())
253 {
254
1/2
✓ Branch 0 taken 175163 times.
✗ Branch 1 not taken.
175163 if (layer == 0) break;
255 175163 continue;
256 }
257
258 84565 rpos_t base_rpos = POS_TO_RPOS(0, get_region_relative_dx(screen), get_region_relative_dy(screen));
259 84565 current_region_rpos_handles[current_region_screen_count] = {scr, screen, layer, base_rpos, 0};
260 84565 current_region_screen_count += 1;
261 84565 }
262
263 37104 int num_handles_for_scr = current_region_screen_count - index_start;
264 37104 current_region_rpos_handles_scr[screen] = {&current_region_rpos_handles[index_start], num_handles_for_scr};
265 37104 }
266 36208 }
267 35860 }
268
269 1782358524 std::tuple<const rpos_handle_t*, int> get_current_region_handles()
270 {
271 DCHECK(!current_region_rpos_handles_dirty);
272 1782358524 return {current_region_rpos_handles, current_region_screen_count};
273 }
274
275 11056525 std::tuple<const rpos_handle_t*, int> get_current_region_handles(mapscr* scr)
276 {
277 DCHECK(!current_region_rpos_handles_dirty);
278
2/4
✓ Branch 0 taken 11056525 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11056525 times.
11056525 if (scr == special_warp_return_scr || current_region_rpos_handles_dirty)
279 return {nullptr, 0};
280
281
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11056525 times.
11056525 if (cur_screen >= 0x80)
282 {
283 DCHECK(scr == origin_scr);
284 return {nullptr, 0};
285 }
286
287 DCHECK(is_in_current_region(scr));
288 11056525 return current_region_rpos_handles_scr[scr->screen];
289 11056525 }
290
291 35860 void mark_current_region_handles_dirty()
292 {
293 35860 current_region_rpos_handles_dirty = true;
294 35860 }
295
296 37003 void clear_temporary_screens()
297 {
298
2/2
✓ Branch 0 taken 35226856 times.
✓ Branch 1 taken 37003 times.
35263859 for (int i = 0; i < 136*7; i++)
299 {
300
2/2
✓ Branch 0 taken 35172221 times.
✓ Branch 1 taken 54635 times.
35226856 if (temporary_screens[i])
301 {
302 54635 free(temporary_screens[i]);
303 54635 temporary_screens[i] = NULL;
304 54635 }
305 35226856 }
306
307 37003 origin_scr = nullptr;
308 37003 hero_scr = nullptr;
309 37003 }
310
311 27954 std::vector<mapscr*> take_temporary_scrs()
312 {
313
1/2
✓ Branch 0 taken 27954 times.
✗ Branch 1 not taken.
27954 std::vector<mapscr*> screens(temporary_screens, temporary_screens + 136*7);
314
2/2
✓ Branch 0 taken 27954 times.
✓ Branch 1 taken 26612208 times.
26640162 for (int i = 0; i < 136*7; i++)
315 26612208 temporary_screens[i] = nullptr;
316
317 27954 return screens;
318
1/2
✓ Branch 0 taken 27954 times.
✗ Branch 1 not taken.
27954 }
319
320 14550090 void calculate_viewport(viewport_t& viewport, int dmap, int screen, int world_w, int world_h, int x, int y)
321 {
322 // TODO: In future, maybe add x/y centering offsets to zscript (Viewport->TargetXOffset/Viewport->TargetYOffset).
323
324
2/2
✓ Branch 0 taken 14503508 times.
✓ Branch 1 taken 46582 times.
14550090 bool extended_height_mode = (DMaps[dmap].flags & dmfEXTENDEDVIEWPORT) && world_h > 176;
325 14550090 viewport.w = 256;
326 14550090 viewport.h = 176 + (extended_height_mode ? 56 : 0);
327
328
2/2
✓ Branch 0 taken 360 times.
✓ Branch 1 taken 14549730 times.
14550090 if (viewport_mode == ViewportMode::Script)
329 360 return;
330
331
2/2
✓ Branch 0 taken 46162 times.
✓ Branch 1 taken 14503568 times.
14549730 if (!is_a_region(DMaps[dmap].map, screen))
332 {
333 14503568 viewport.x = 0;
334 14503568 viewport.y = 0;
335 14503568 }
336
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46162 times.
46162 else if (viewport_mode == ViewportMode::CenterAndBound)
337 {
338 // Clamp the viewport to the edges of the region.
339
6/6
✓ Branch 0 taken 8568 times.
✓ Branch 1 taken 37594 times.
✓ Branch 2 taken 6788 times.
✓ Branch 3 taken 39374 times.
✓ Branch 4 taken 8568 times.
✓ Branch 5 taken 30806 times.
46162 viewport.x = CLAMP(0, world_w - viewport.w, x - viewport.w/2);
340
6/6
✓ Branch 0 taken 11856 times.
✓ Branch 1 taken 34306 times.
✓ Branch 2 taken 5650 times.
✓ Branch 3 taken 40512 times.
✓ Branch 4 taken 11856 times.
✓ Branch 5 taken 28656 times.
46162 viewport.y = CLAMP(0, world_h - viewport.h, y - viewport.h/2);
341 46162 }
342 else if (viewport_mode == ViewportMode::Center)
343 {
344 viewport.x = x - viewport.w/2;
345 viewport.y = y - viewport.h/2;
346 }
347 14550090 }
348
349 14549579 sprite* get_viewport_sprite()
350 {
351 14549579 sprite* spr = sprite::getByUID(viewport_sprite_uid);
352
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 14549573 times.
14549579 if (!spr)
353 {
354 6 viewport_sprite_uid = 1; // Hero uid.
355 6 spr = &Hero;
356 6 }
357
358 14549579 return spr;
359 }
360
361 6 void set_viewport_sprite(sprite* spr)
362 {
363 6 viewport_sprite_uid = spr->uid;
364 6 }
365
366 14521625 void update_viewport()
367 {
368 14521625 sprite* spr = get_viewport_sprite();
369 14521625 int x = spr->x + spr->txsz*16/2;
370 14521625 int y = spr->y + spr->tysz*16/2;
371 14521625 calculate_viewport(viewport, cur_dmap, cur_screen, world_w, world_h, x, y);
372 14521625 }
373
374 14309414 void update_heroscr()
375 {
376 void playLevelMusic();
377
378 14309414 int x = vbound(Hero.getX().getInt(), 0, world_w - 1);
379 14309414 int y = vbound(Hero.getY().getInt(), 0, world_h - 1);
380 14309414 int dx = x / 256;
381 14309414 int dy = y / 176;
382 14309414 int new_screen = cur_screen + dx + dy * 16;
383
2/2
✓ Branch 0 taken 14301652 times.
✓ Branch 1 taken 7762 times.
14309414 if (maze_state.active == 1)
384 7762 new_screen = maze_state.scr->screen;
385
7/12
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 14309198 times.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 216 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 216 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 216 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 216 times.
14309414 if (hero_screen != new_screen && dx >= 0 && dy >= 0 && dx < 16 && dy < 8 && is_in_current_region(new_screen))
386 {
387 216 region_scr_dx = dx;
388 216 region_scr_dy = dy;
389 216 hero_screen = new_screen;
390 216 prev_hero_scr = hero_scr;
391 216 hero_scr = get_scr(hero_screen);
392 216 Hero.screen_spawned = hero_screen;
393 216 playLevelMusic();
394 216 }
395
1/2
✓ Branch 0 taken 14309414 times.
✗ Branch 1 not taken.
14309414 if (game->get_regionmapping() == REGION_MAPPING_PHYSICAL)
396 mark_visited(new_screen); // Mark each screen the hero steps foot in as visited
397 14309414 }
398
399 4722 mapscr* determine_hero_screen_from_coords()
400 {
401 4722 int x = vbound(Hero.getX().getInt(), 0, world_w - 1);
402 4722 int y = vbound(Hero.getY().getInt(), 0, world_h - 1);
403 4722 int dx = x / 256;
404 4722 int dy = y / 176;
405 4722 return get_scr(cur_screen + dx + dy * 16);
406 }
407
408 26924 bool edge_of_region(direction dir)
409 {
410
2/2
✓ Branch 0 taken 26844 times.
✓ Branch 1 taken 80 times.
26924 if (!is_in_scrolling_region()) return true;
411
412 80 int screen_x = hero_screen % 16;
413 80 int screen_y = hero_screen / 16;
414
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 2 times.
80 if (dir == up) screen_y -= 1;
415
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 10 times.
80 if (dir == down) screen_y += 1;
416
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 30 times.
80 if (dir == left) screen_x -= 1;
417
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 38 times.
80 if (dir == right) screen_x += 1;
418
4/8
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 80 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 80 times.
✗ Branch 7 not taken.
80 if (screen_x < 0 || screen_x > 16 || screen_y < 0 || screen_y > 8) return true;
419 80 return !is_in_current_region(map_scr_xy_to_index(screen_x, screen_y));
420 26924 }
421
422 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
423 // Coordinates are clamped to the world bounds.
424 212153639 int get_screen_for_world_xy(int x, int y)
425 {
426
2/2
✓ Branch 0 taken 189364027 times.
✓ Branch 1 taken 22789612 times.
212153639 if (!is_in_scrolling_region())
427 189364027 return cur_screen;
428
429 22789612 int dx = std::clamp(x, 0, world_w - 1) / 256;
430 22789612 int dy = std::clamp(y, 0, world_h - 1) / 176;
431 22789612 int origin_screen_x = cur_screen % 16;
432 22789612 int origin_screen_y = cur_screen / 16;
433 22789612 int scr_x = origin_screen_x + dx;
434 22789612 int scr_y = origin_screen_y + dy;
435 22789612 return map_scr_xy_to_index(scr_x, scr_y);
436 212153639 }
437
438 32518504 int get_screen_for_rpos(rpos_t rpos)
439 {
440 32518504 int origin_screen_x = cur_screen % 16;
441 32518504 int origin_screen_y = cur_screen / 16;
442 32518504 int screen = static_cast<int32_t>(rpos) / 176;
443 32518504 int scr_x = origin_screen_x + screen%cur_region.screen_width;
444 32518504 int scr_y = origin_screen_y + screen/cur_region.screen_width;
445 32518504 return map_scr_xy_to_index(scr_x, scr_y);
446 }
447
448 774411719 rpos_handle_t get_rpos_handle(rpos_t rpos, int layer)
449 {
450 DCHECK_LAYER_ZERO_INDEX(layer);
451
2/2
✓ Branch 0 taken 742031175 times.
✓ Branch 1 taken 32380544 times.
774411719 if (!is_in_scrolling_region())
452 742031175 return {get_scr_layer(cur_screen, layer), cur_screen, layer, rpos, RPOS_TO_POS(rpos)};
453 32380544 int screen = get_screen_for_rpos(rpos);
454 32380544 mapscr* scr = get_scr_layer(screen, layer);
455 32380544 return {scr, screen, layer, rpos, RPOS_TO_POS(rpos)};
456 774411719 }
457
458 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
459 // Coordinates are clamped to the world bounds.
460 3502385070 rpos_handle_t get_rpos_handle_for_world_xy(int x, int y, int layer)
461 {
462 3502385070 x = std::clamp(x, 0, world_w - 1);
463 3502385070 y = std::clamp(y, 0, world_h - 1);
464
465 DCHECK_LAYER_ZERO_INDEX(layer);
466
2/2
✓ Branch 0 taken 3474647898 times.
✓ Branch 1 taken 27737172 times.
3502385070 if (!is_in_scrolling_region())
467 {
468 3474647898 int pos = COMBOPOS(x, y);
469 3474647898 return {get_scr_layer(cur_screen, layer), cur_screen, layer, (rpos_t)pos, pos};
470 }
471 27737172 return get_rpos_handle(COMBOPOS_REGION(x, y), layer);
472 3502385070 }
473
474 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
475 1926 rpos_handle_t get_rpos_handle_for_screen(int screen, int layer, int pos)
476 {
477 DCHECK_LAYER_ZERO_INDEX(layer);
478 1926 return {get_scr_layer(screen, layer), screen, layer, POS_TO_RPOS(pos, screen), pos};
479 }
480
481 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
482 // Use this instead of the other `get_pos_handle_for_screen` if you already have a reference to the screen.
483 62247 rpos_handle_t get_rpos_handle_for_scr(mapscr* scr, int layer, int pos)
484 {
485 DCHECK_LAYER_ZERO_INDEX(layer);
486 62247 return {scr, scr->screen, layer, POS_TO_RPOS(pos, scr->screen), pos};
487 }
488
489 25183249 void change_rpos_handle_layer(rpos_handle_t& rpos_handle, int layer)
490 {
491 DCHECK_LAYER_ZERO_INDEX(layer);
492 25183249 rpos_handle.layer = layer;
493 25183249 rpos_handle.scr = get_scr_layer(rpos_handle.screen, layer);
494 25183249 }
495
496 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
497 // Coordinates are clamped to the world bounds.
498 52808 combined_handle_t get_combined_handle_for_world_xy(int x, int y, int layer)
499 {
500 DCHECK_LAYER_ZERO_INDEX(layer);
501
502 52808 x = std::clamp(x, 0, world_w - 1);
503 52808 y = std::clamp(y, 0, world_h - 1);
504
505 52808 auto maybe_ffc_handle = getFFCAt(x, y);
506
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52808 times.
52808 if (maybe_ffc_handle)
507 return maybe_ffc_handle.value();
508
509 52808 auto rpos = COMBOPOS_REGION_B(x, y);
510
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52808 times.
52808 if (rpos == rpos_t::None)
511 return rpos_handle_t();
512 52808 return get_rpos_handle(rpos, layer);
513 52808 }
514
515 // These functions all return _temporary_ screens. Any modifications made to them (either by the engine
516 // directly or via zscript) only last until the next area is loaded (via loadscr).
517
518 // Returns the screen containing the (x, y) world position.
519 1633912286 mapscr* get_scr_for_world_xy(int x, int y)
520 {
521 // Quick path, but should work the same without.
522
2/2
✓ Branch 0 taken 1622779286 times.
✓ Branch 1 taken 11133000 times.
1633912286 if (!is_in_scrolling_region()) return origin_scr;
523 11133000 return get_scr(get_screen_for_world_xy(x, y));
524 1633912286 }
525
526 24512754 mapscr* get_scr_for_rpos(rpos_t rpos)
527 {
528 // Quick path, but should work the same without.
529
2/2
✓ Branch 0 taken 24374808 times.
✓ Branch 1 taken 137946 times.
24512754 if (!is_in_scrolling_region()) return origin_scr;
530 137946 return get_scr(get_screen_for_rpos(rpos));
531 24512754 }
532
533 14 mapscr* get_scr_for_rpos_layer(rpos_t rpos, int layer)
534 {
535 14 return get_scr_layer(get_screen_for_rpos(rpos), layer);
536 }
537
538 // Note: layer=0 is the base screen, 1 is the first layer, etc.
539 2308651934 mapscr* get_scr_for_world_xy_layer(int x, int y, int layer)
540 {
541 DCHECK_LAYER_ZERO_INDEX(layer);
542
2/2
✓ Branch 0 taken 2297231936 times.
✓ Branch 1 taken 11419998 times.
2308651934 if (!is_in_scrolling_region()) return get_scr_layer(cur_screen, layer);
543
2/2
✓ Branch 0 taken 708934 times.
✓ Branch 1 taken 10711064 times.
11419998 return layer == 0 ?
544 708934 get_scr_for_world_xy(x, y) :
545 10711064 get_scr_layer(get_screen_for_world_xy(x, y), layer);
546 2308651934 }
547
548 1833562055 int get_region_screen_offset(int screen)
549 {
550 1833562055 return get_region_relative_dx(screen) + get_region_relative_dy(screen) * cur_region.screen_width;
551 }
552
553 654676696 int get_screen_for_region_index_offset(int offset)
554 {
555 654676696 int scr_dx = offset % cur_region.screen_width;
556 654676696 int scr_dy = offset / cur_region.screen_width;
557 654676696 int screen = cur_screen + scr_dx + scr_dy*16;
558 654676696 return screen;
559 }
560
561 654492859 mapscr* get_scr_for_region_index_offset(int offset)
562 {
563 654492859 int screen = get_screen_for_region_index_offset(offset);
564 654492859 return get_scr(screen);
565 }
566
567 // The screen at (map, screen) must exist.
568 1421742368 mapscr* get_scr(int map, int screen)
569 {
570 1421742368 mapscr* scr = get_scr_maybe(map, screen);
571
1/2
✓ Branch 0 taken 1421742368 times.
✗ Branch 1 not taken.
1421742368 CHECK(scr);
572 1421742368 return scr;
573 }
574
575 837456751 mapscr* get_scr(int screen)
576 {
577 837456751 return get_scr(cur_map, screen);
578 }
579
580 // Returns null if active screen does not exist.
581 1451287411 mapscr* get_scr_maybe(int map, int screen)
582 {
583 DCHECK_RANGE_INCLUSIVE(screen, 0, 135);
584
585
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1451287411 times.
1451287411 if (map == cur_map)
586 {
587
2/2
✓ Branch 0 taken 1430512479 times.
✓ Branch 1 taken 20774932 times.
1451287411 if (screen == cur_screen)
588 1430512479 return origin_scr;
589
590 20774932 int index = screen*7;
591
2/2
✓ Branch 0 taken 20763842 times.
✓ Branch 1 taken 11090 times.
20774932 if (temporary_screens[index])
592 20763842 return temporary_screens[index];
593
594
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11090 times.
11090 if (screen == home_screen)
595 return special_warp_return_scr;
596 11090 }
597
598
3/6
✓ Branch 0 taken 11090 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11090 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11090 times.
11090 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
599 {
600 11090 int index = screen*7;
601
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11090 times.
11090 if (FFCore.ScrollingScreensAll[index])
602 11090 return FFCore.ScrollingScreensAll[index];
603 }
604
605 return nullptr;
606 1451287411 }
607
608 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
609 7063660436 mapscr* get_scr_layer(int map, int screen, int layer)
610 {
611 DCHECK_LAYER_ZERO_INDEX(layer);
612
2/2
✓ Branch 0 taken 6481867503 times.
✓ Branch 1 taken 581792933 times.
7063660436 if (layer == 0)
613 581792933 return get_scr(map, screen);
614
615
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6481867503 times.
6481867503 if (map == cur_map)
616 {
617 6481867503 int index = screen*7 + layer;
618
2/2
✓ Branch 0 taken 6481799103 times.
✓ Branch 1 taken 68400 times.
6481867503 if (temporary_screens[index])
619 6481799103 return temporary_screens[index];
620
621
2/2
✓ Branch 0 taken 1860 times.
✓ Branch 1 taken 66540 times.
68400 if (screen == home_screen)
622 1860 return &special_warp_return_scrs[layer];
623 66540 }
624
625
1/2
✓ Branch 0 taken 66540 times.
✗ Branch 1 not taken.
66540 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
626 {
627 66540 int index = screen*7 + layer;
628
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66540 times.
66540 if (FFCore.ScrollingScreensAll[index])
629 66540 return FFCore.ScrollingScreensAll[index];
630 }
631
632 NOTREACHED();
633 7063660436 }
634
635 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
636 6664515076 mapscr* get_scr_layer(int screen, int layer)
637 {
638 6664515076 return get_scr_layer(cur_map, screen, layer);
639 }
640
641 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
642 // Return nullptr if screen is not valid.
643 397071557 mapscr* get_scr_layer_valid(int screen, int layer)
644 {
645
2/2
✓ Branch 0 taken 78265285 times.
✓ Branch 1 taken 318806272 times.
397071557 if (mapscr* scr = get_scr_layer(cur_map, screen, layer); scr->is_valid())
646 78265285 return scr;
647 318806272 return nullptr;
648 397071557 }
649
650 401 mapscr* get_scr_current_region_dir(int screen, direction dir)
651 {
652 401 int x = get_region_relative_dx(screen);
653 401 int y = get_region_relative_dy(screen);
654
3/4
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 330 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 71 times.
401 if (dir == left && x == 0)
655 71 return nullptr;
656
3/4
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 238 times.
✓ Branch 2 taken 92 times.
✗ Branch 3 not taken.
330 if (dir == right && x == 15)
657 return nullptr;
658
3/4
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 281 times.
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
330 if (dir == down && y == 7)
659 return nullptr;
660
3/4
✓ Branch 0 taken 189 times.
✓ Branch 1 taken 141 times.
✓ Branch 2 taken 189 times.
✗ Branch 3 not taken.
330 if (dir == up && y == 0)
661 189 return nullptr;
662
663 141 screen = screen_index_direction(screen, dir);
664
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141 times.
141 if (is_in_current_region(screen))
665 return get_scr(screen);
666
667 141 return nullptr;
668 401 }
669
670 183837 ffc_handle_t get_ffc_handle(ffc_id_t id)
671 {
672 183837 uint8_t screen = get_screen_for_region_index_offset(id / MAXFFCS);
673 183837 uint8_t i = id % MAXFFCS;
674 183837 mapscr* scr = get_scr(screen);
675 183837 ffcdata* ffc = &scr->getFFC(id % MAXFFCS);
676 183837 return {scr, screen, id, i, ffc};
677 }
678
679 34566 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen, int x, int y)
680 {
681 34566 x += get_region_relative_dx(screen) * 256;
682 34566 y += get_region_relative_dy(screen) * 176;
683 34566 return {x, y};
684 }
685
686 1049504 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen)
687 {
688 1049504 int x = get_region_relative_dx(screen) * 256;
689 1049504 int y = get_region_relative_dy(screen) * 176;
690 1049504 return {x, y};
691 }
692
693 12140034006 int32_t COMBOPOS(int32_t x, int32_t y)
694 {
695 DCHECK(x >= 0 && x < 256 && y >= 0 && y < 176);
696 12140034006 return (y & 0xF0) + (x >> 4);
697 }
698 int32_t COMBOPOS_B(int32_t x, int32_t y)
699 {
700 if(unsigned(x) >= 256 || unsigned(y) >= 176)
701 return -1;
702 return (y & 0xF0) + (x >> 4);
703 }
704 3334372240 int32_t COMBOX(int32_t pos)
705 {
706 3334372240 return pos % 16 * 16;
707 }
708 3334372240 int32_t COMBOY(int32_t pos)
709 {
710 3334372240 return pos & 0xF0;
711 }
712
713 112622827 rpos_t COMBOPOS_REGION(int32_t x, int32_t y)
714 {
715
2/2
✓ Branch 0 taken 84070181 times.
✓ Branch 1 taken 28552646 times.
112622827 if (!is_in_scrolling_region())
716 84070181 return (rpos_t) COMBOPOS(x, y);
717
718 DCHECK(is_in_world_bounds(x, y));
719 28552646 int scr_dx = x / (16*16);
720 28552646 int scr_dy = y / (11*16);
721 28552646 int pos = COMBOPOS(x%256, y%176);
722 28552646 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
723 112622827 }
724 6304649622 rpos_t COMBOPOS_REGION_B(int32_t x, int32_t y)
725 {
726
2/2
✓ Branch 0 taken 1397625 times.
✓ Branch 1 taken 6303251997 times.
6304649622 if (!is_in_world_bounds(x, y))
727 1397625 return rpos_t::None;
728
729 6303251997 int scr_dx = x / (16*16);
730 6303251997 int scr_dy = y / (11*16);
731 6303251997 int pos = COMBOPOS(x%256, y%176);
732 6303251997 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
733 6304649622 }
734 25286716 std::pair<int32_t, int32_t> COMBOXY_REGION(rpos_t rpos)
735 {
736 25286716 int scr_index = static_cast<int32_t>(rpos) / 176;
737 25286716 int scr_dx = scr_index % cur_region.screen_width;
738 25286716 int scr_dy = scr_index / cur_region.screen_width;
739 25286716 int pos = RPOS_TO_POS(rpos);
740 25286716 int x = scr_dx*16*16 + COMBOX(pos);
741 25286716 int y = scr_dy*11*16 + COMBOY(pos);
742 25286716 return {x, y};
743 }
744 60396 int32_t COMBOX_REGION(rpos_t rpos)
745 {
746 60396 auto [x, y] = COMBOXY_REGION(rpos);
747 60396 return x;
748 }
749 12225 int32_t COMBOY_REGION(rpos_t rpos)
750 {
751 12225 auto [x, y] = COMBOXY_REGION(rpos);
752 12225 return y;
753 }
754
755 70177 rpos_t COMBOPOS_REGION_INDEX(int32_t x, int32_t y)
756 {
757 DCHECK(is_in_world_bounds(x, y));
758
1/2
✓ Branch 0 taken 70177 times.
✗ Branch 1 not taken.
70177 if (!is_in_scrolling_region())
759 70177 return (rpos_t)(x + y * 16);
760
761 int scr_dx = x / 16;
762 int scr_dy = y / 11;
763 x %= 16;
764 y %= 11;
765 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + x + y * 16);
766 70177 }
767 70632 std::pair<int32_t, int32_t> COMBOXY_REGION_INDEX(rpos_t rpos)
768 {
769 70632 int scr_index = static_cast<int32_t>(rpos) / 176;
770 70632 int scr_dx = scr_index % cur_region.screen_width;
771 70632 int scr_dy = scr_index / cur_region.screen_width;
772 70632 int pos = RPOS_TO_POS(rpos);
773 70632 int x = scr_dx*16 + pos%16;
774 70632 int y = scr_dy*11 + pos/16;
775 70632 return {x, y};
776 }
777
778 82516944 int32_t mapind(int32_t map, int32_t scr)
779 {
780 82516944 return map * MAPSCRSNORMAL + scr;
781 }
782
783 FONT *get_zc_font(int index);
784
785 extern sprite_list guys, items, Ewpns, Lwpns, chainlinks, decorations;
786 extern movingblock mblock2; //mblock[4]?
787 extern portal mirror_portal;
788
789 void Z_message_d(const char *format,...)
790 {
791 #ifdef _DEBUG
792 char buf[512];
793 va_list ap;
794 va_start(ap, format);
795 vsprintf(buf, format, ap);
796 va_end(ap);
797
798 al_trace("%s",buf);
799 #else
800 format=format;
801 #endif
802 }
803
804
805
806 bool checktrigger=false;
807
808 void debugging_box(int32_t x1, int32_t y1, int32_t x2, int32_t y2)
809 {
810 //reference/optimization: the start of the unused drawing command index can now be queried. -Gleeok
811 int32_t index = script_drawing_commands.GetNext();
812
813 if(index < 0)
814 return;
815
816 int32_t *sdci = &script_drawing_commands[index][0];
817
818 sdci[0] = RECTR;
819 sdci[1] = 30000;
820 sdci[2] = x1*10000;
821 sdci[3] = y1*10000;
822 sdci[4] = x2*10000;
823 sdci[5] = y2*10000;
824 sdci[6] = 10000;
825 sdci[7] = 10000;
826 sdci[8] = 0;
827 sdci[9] = 0;
828 sdci[10] = 0;
829 sdci[11] = 10000;
830 sdci[12] = 1280000;
831 }
832
833 void clear_dmap(word i)
834 {
835 DMaps[i].clear();
836 }
837
838 void clear_dmaps()
839 {
840 for(int32_t i=0; i<MAXDMAPS; i++)
841 {
842 clear_dmap(i);
843 }
844 }
845
846 223615703 int32_t isdungeon(int32_t dmap, int32_t screen)
847 {
848
2/2
✓ Branch 0 taken 223570023 times.
✓ Branch 1 taken 45680 times.
223615703 if (dmap < 0) dmap = cur_dmap;
849
850 // dungeons can have any dlevel above 0
851
2/2
✓ Branch 0 taken 122366258 times.
✓ Branch 1 taken 101249445 times.
223615703 if((DMaps[dmap].type&dmfTYPE) == dmDNGN)
852 {
853
2/2
✓ Branch 0 taken 9961 times.
✓ Branch 1 taken 101239484 times.
101249445 if (get_canonical_scr(cur_map, screen)->flags6&fCAVEROOM)
854 9961 return 0;
855
856 101239484 return 1;
857 }
858
859 // dlevels that aren't dungeons are caves
860
2/2
✓ Branch 0 taken 36827 times.
✓ Branch 1 taken 122329431 times.
122366258 if (get_canonical_scr(cur_map, screen)->flags6&fDUNGEONROOM)
861 36827 return 1;
862
863 122329431 return 0;
864 223615703 }
865
866 39942474 int32_t isdungeon(int32_t screen)
867 {
868 39942474 return isdungeon(cur_dmap, screen);
869 }
870
871 183546280 int32_t isdungeon()
872 {
873 183546280 return isdungeon(cur_dmap, hero_screen);
874 }
875
876 88938 bool canPermSecret(int32_t dmap, int32_t screen)
877 {
878
2/2
✓ Branch 0 taken 13910 times.
✓ Branch 1 taken 75028 times.
88938 return (!isdungeon(dmap, screen) || get_qr(qr_DUNGEON_DMAPS_PERM_SECRETS));
879 }
880
881 1375769828 int32_t MAPCOMBO(int32_t x, int32_t y)
882 {
883 1375769828 x = vbound(x, 0, world_w-1);
884 1375769828 y = vbound(y, 0, world_h-1);
885 1375769828 int pos = COMBOPOS(x%256, y%176);
886 1375769828 mapscr* scr = get_scr_for_world_xy(x, y);
887 1375769828 return scr->data[pos];
888 }
889
890 //specific layers 1 to 6
891 1709728026 int32_t MAPCOMBOL(int32_t layer,int32_t x,int32_t y)
892 {
893 DCHECK(layer >= 1 && layer <= 6);
894
3/4
✓ Branch 0 taken 1689370044 times.
✓ Branch 1 taken 20357982 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1689370044 times.
1709728026 if (!is_in_world_bounds(x, y) || layer <= 0)
895 20357982 return 0;
896
897 1689370044 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
898
2/2
✓ Branch 0 taken 496888043 times.
✓ Branch 1 taken 1192482001 times.
1689370044 if (!m->is_valid())
899 1192482001 return 0;
900
901 496888043 int pos = COMBOPOS(x%256, y%176);
902 496888043 return m->data[pos];
903 1709728026 }
904
905 int32_t MAPCSETL(int32_t layer,int32_t x,int32_t y)
906 {
907 DCHECK(layer >= 1 && layer <= 6);
908 if (!is_in_world_bounds(x, y) || layer <= 0)
909 return 0;
910
911 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
912 if (!m->is_valid())
913 return 0;
914
915 int pos = COMBOPOS(x%256, y%176);
916 return m->cset[pos];
917 }
918
919 189308 int32_t MAPFLAGL(int32_t layer,int32_t x,int32_t y)
920 {
921 DCHECK(layer >= 1 && layer <= 6);
922
2/4
✓ Branch 0 taken 189308 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 189308 times.
189308 if (!is_in_world_bounds(x, y) || layer <= 0)
923 return 0;
924
925 189308 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
926
2/2
✓ Branch 0 taken 148914 times.
✓ Branch 1 taken 40394 times.
189308 if (!m->is_valid())
927 40394 return 0;
928
929 148914 int pos = COMBOPOS(x%256, y%176);
930 148914 return m->sflag[pos];
931 189308 }
932
933 6281 int32_t COMBOTYPEL(int32_t layer,int32_t x,int32_t y)
934 {
935 DCHECK(layer >= 1 && layer <= 6);
936
2/4
✓ Branch 0 taken 6281 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6281 times.
6281 if (!is_in_world_bounds(x, y) || layer <= 0)
937 return 0;
938
939 6281 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
940
2/2
✓ Branch 0 taken 5809 times.
✓ Branch 1 taken 472 times.
6281 if (!m->is_valid())
941 472 return 0;
942
943 5809 int pos = COMBOPOS(x%256, y%176);
944 5809 return combobuf[m->data[pos]].type;
945 6281 }
946
947 189308 int32_t MAPCOMBOFLAGL(int32_t layer,int32_t x,int32_t y)
948 {
949 DCHECK(layer >= 1 && layer <= 6);
950
2/4
✓ Branch 0 taken 189308 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 189308 times.
189308 if (!is_in_world_bounds(x, y) || layer <= 0)
951 return 0;
952
953 189308 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
954
2/2
✓ Branch 0 taken 148914 times.
✓ Branch 1 taken 40394 times.
189308 if (!m->is_valid())
955 40394 return 0;
956
957 148914 int pos = COMBOPOS(x%256, y%176);
958 148914 return combobuf[m->data[pos]].flag;
959 189308 }
960
961
962 // True if the FFC covers x, y and is not ethereal or a changer.
963 2467525264 bool ffcIsAt(const ffc_handle_t& ffc_handle, int32_t x, int32_t y)
964 {
965
2/2
✓ Branch 0 taken 746716438 times.
✓ Branch 1 taken 1720808826 times.
2467525264 if (ffc_handle.data()<=0)
966 746716438 return false;
967
968
2/2
✓ Branch 0 taken 300884516 times.
✓ Branch 1 taken 1419924310 times.
1720808826 if((ffc_handle.ffc->flags&(ffc_changer|ffc_ethereal))!=0)
969 300884516 return false;
970
971 1419924310 int32_t fx=ffc_handle.ffc->x.getInt();
972
4/4
✓ Branch 0 taken 976336659 times.
✓ Branch 1 taken 443587651 times.
✓ Branch 2 taken 866205591 times.
✓ Branch 3 taken 110131068 times.
1419924310 if(x<fx || x>fx+(ffc_handle.scr->ffEffectWidth(ffc_handle.i)-1)) // FFC sizes are weird.
973 1309793242 return false;
974
975 110131068 int32_t fy=ffc_handle.ffc->y.getInt();
976
4/4
✓ Branch 0 taken 80147059 times.
✓ Branch 1 taken 29984009 times.
✓ Branch 2 taken 60079259 times.
✓ Branch 3 taken 20067800 times.
110131068 if(y<fy || y>fy+(ffc_handle.scr->ffEffectHeight(ffc_handle.i)-1))
977 90063268 return false;
978
979 20067800 return true;
980 2467525264 }
981
982 999075725 int32_t MAPFFCOMBO(int32_t x,int32_t y)
983 {
984
2/2
✓ Branch 0 taken 13163663 times.
✓ Branch 1 taken 985912062 times.
999075725 if (auto ffc_handle = getFFCAt(x, y))
985 13163663 return ffc_handle->data();
986 985912062 return 0;
987 999075725 }
988
989 207232 int32_t MAPCSET(int32_t x, int32_t y)
990 {
991
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 207232 times.
207232 if (!is_in_world_bounds(x, y))
992 return 0;
993 207232 mapscr* scr = get_scr_for_world_xy(x, y);
994 207232 int pos = COMBOPOS(x%256, y%176);
995 207232 return scr->cset[pos];
996 207232 }
997
998 73664988 int32_t MAPFLAG(int32_t x, int32_t y)
999 {
1000
2/2
✓ Branch 0 taken 28140 times.
✓ Branch 1 taken 73636848 times.
73664988 if (!is_in_world_bounds(x, y))
1001 28140 return 0;
1002 73636848 mapscr* scr = get_scr_for_world_xy(x, y);
1003 73636848 int pos = COMBOPOS(x%256, y%176);
1004 73636848 return scr->sflag[pos];
1005 73664988 }
1006
1007 165703047 int32_t COMBOTYPE(int32_t x,int32_t y)
1008 {
1009 165703047 int32_t b=1;
1010
2/2
✓ Branch 0 taken 96762393 times.
✓ Branch 1 taken 68940654 times.
165703047 if(x&8) b<<=2;
1011
2/2
✓ Branch 0 taken 83462716 times.
✓ Branch 1 taken 82240331 times.
165703047 if(y&8) b<<=1;
1012
1013
2/2
✓ Branch 0 taken 331399056 times.
✓ Branch 1 taken 165695748 times.
497094804 for (int32_t i = 0; i <= 1; ++i)
1014 {
1015
2/2
✓ Branch 0 taken 320242340 times.
✓ Branch 1 taken 11156716 times.
331399056 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1016 {
1017
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 320242340 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
320242340 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x, y, i)) return cNONE;
1018 320242340 }
1019 else
1020 {
1021
4/4
✓ Branch 0 taken 10451 times.
✓ Branch 1 taken 11146265 times.
✓ Branch 2 taken 3152 times.
✓ Branch 3 taken 7299 times.
11156716 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x, y, i)) return cNONE;
1022 }
1023 331391757 }
1024
1025 165695748 newcombo const& cmb = combobuf[MAPCOMBO(x,y)];
1026
5/6
✓ Branch 0 taken 3652838 times.
✓ Branch 1 taken 162042910 times.
✓ Branch 2 taken 3069902 times.
✓ Branch 3 taken 582936 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3069902 times.
165695748 if (cmb.type == cWATER && (cmb.walk&b) && ((cmb.walk>>4)&b))
1027 {
1028
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3069902 times.
3069902 if(cmb.usrflags&cflag4) return cSHALLOWWATER;
1029
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3069902 times.
3069902 if(cmb.usrflags&cflag3) return cNONE;
1030 3069902 }
1031 165695748 return cmb.type;
1032 165703047 }
1033
1034 50225955 int32_t FFCOMBOTYPE(int32_t x,int32_t y)
1035 {
1036 50225955 return combobuf[MAPFFCOMBO(x,y)].type;
1037 }
1038
1039 4954836 int32_t FFORCOMBO(int32_t x, int32_t y)
1040 {
1041
2/2
✓ Branch 0 taken 58516 times.
✓ Branch 1 taken 4896320 times.
4954836 if (auto ffc_handle = getFFCAt(x, y))
1042 58516 return ffc_handle->data();
1043
1044 4896320 return MAPCOMBO(x,y);
1045 4954836 }
1046
1047 int32_t FFORCOMBOTYPE(int32_t x, int32_t y)
1048 {
1049 for (int32_t i = 0; i <= 1; ++i)
1050 {
1051 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1052 {
1053 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1054 }
1055 else
1056 {
1057 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1058 }
1059 }
1060 int32_t b=1;
1061
1062 if(x&8) b<<=2;
1063
1064 if(y&8) b<<=1;
1065 newcombo const& cmb = combobuf[FFORCOMBO(x,y)];
1066 if (cmb.type == cWATER && (cmb.usrflags&cflag4) && (cmb.walk&b)) return cSHALLOWWATER;
1067 if (cmb.type == cWATER && (cmb.usrflags&cflag3) && (cmb.walk&b)) return cNONE;
1068 return cmb.type;
1069 }
1070
1071 int32_t FFORCOMBO_L(int32_t layer, int32_t x, int32_t y)
1072 {
1073 if (auto ffc_handle = getFFCAt(x, y))
1074 return ffc_handle->data();
1075
1076 return layer ? MAPCOMBOL(layer, x, y) : MAPCOMBO(x,y);
1077 }
1078
1079 int32_t FFORCOMBOTYPE_L(int32_t layer, int32_t x, int32_t y)
1080 {
1081 return combobuf[FFORCOMBO_L(layer,x,y)].type;
1082 }
1083
1084 70154870 int32_t MAPCOMBOFLAG(int32_t x,int32_t y)
1085 {
1086
2/2
✓ Branch 0 taken 27852 times.
✓ Branch 1 taken 70127018 times.
70154870 if (!is_in_world_bounds(x, y))
1087 27852 return 0;
1088
1089 70127018 mapscr* scr = get_scr_for_world_xy(x, y);
1090 70127018 int pos = COMBOPOS(x%256, y%176);
1091 70127018 return combobuf[scr->data[pos]].flag;
1092 70154870 }
1093
1094 56841587 int32_t MAPFFCOMBOFLAG(int32_t x,int32_t y)
1095 {
1096
2/2
✓ Branch 0 taken 746177 times.
✓ Branch 1 taken 56095410 times.
56841587 if (auto ffc_handle = getFFCAt(x, y))
1097 746177 return ffc_handle->cflag();
1098
1099 56095410 return 0;
1100 56841587 }
1101
1102 1313056486 std::optional<ffc_handle_t> getFFCAt(int32_t x, int32_t y)
1103 {
1104 2788859898 return find_ffc([&](const ffc_handle_t& ffc_handle) {
1105 1475803412 return ffcIsAt(ffc_handle, x, y);
1106 });
1107 }
1108
1109 3044 int32_t MAPCOMBO(const rpos_handle_t& rpos_handle)
1110 {
1111
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3044 times.
3044 if (!rpos_handle.scr->is_valid()) return 0;
1112 3044 return rpos_handle.data();
1113 3044 }
1114
1115 3169050674 int32_t MAPCOMBO2(int32_t layer, int32_t x, int32_t y)
1116 {
1117 DCHECK_LAYER_NEG1_INDEX(layer);
1118
2/2
✓ Branch 0 taken 22425886 times.
✓ Branch 1 taken 3146624788 times.
3169050674 if (!is_in_world_bounds(x, y)) return 0;
1119
2/2
✓ Branch 0 taken 3077523526 times.
✓ Branch 1 taken 69101262 times.
3146624788 if (layer == -1) return MAPCOMBO(x, y);
1120
1121 3077523526 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1122
2/2
✓ Branch 0 taken 2118938447 times.
✓ Branch 1 taken 958585079 times.
3077523526 if (!rpos_handle.scr->is_valid()) return 0;
1123
1124 958585079 return rpos_handle.data();
1125 3169050674 }
1126
1127 17372224 static void _handle_screen_load_trigger(const combined_handle_t& handle)
1128 {
1129 17372224 auto cid = handle.data();
1130 17372224 auto* cmb = &handle.combo();
1131 17372224 bool done = false;
1132 17372224 std::set<int32_t> visited;
1133
2/2
✓ Branch 0 taken 17372224 times.
✓ Branch 1 taken 17372224 times.
34744448 while(!done)
1134 {
1135
2/4
✓ Branch 0 taken 17372224 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 17372224 times.
17372224 if(visited.contains(cid))
1136 {
1137 Z_error("Combo '%d' was part of an infinite trigger loop, breaking out of loop", cid);
1138 break; // prevent infinite loop
1139 }
1140
1/2
✓ Branch 0 taken 17372224 times.
✗ Branch 1 not taken.
17372224 visited.insert(cid);
1141
1142 17372224 done = true; // don't loop again unless something changes
1143
1/2
✓ Branch 0 taken 17372224 times.
✗ Branch 1 not taken.
17964179 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
1144 591955 return trig.trigger_flags.get(TRIGFLAG_SCREENLOAD);
1145 });
1146
2/4
✓ Branch 0 taken 17372224 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 17372224 times.
17372224 if(handle.data() != cid)
1147 {
1148 cid = handle.data();
1149 cmb = &handle.combo();
1150 done = false; // loop again for the new combo
1151 }
1152 }
1153 17372224 }
1154 51767 static void handle_screen_load_trigger(const screen_handles_t& screen_handles)
1155 {
1156 51767 for_every_combo_in_screen(screen_handles, _handle_screen_load_trigger);
1157 51767 }
1158 34819 void handle_region_load_trigger()
1159 {
1160
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 34667 times.
34819 if (is_in_scrolling_region())
1161 {
1162
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 19456 times.
19608 for (int screen = 0; screen < 128; screen++)
1163 {
1164
2/2
✓ Branch 0 taken 18156 times.
✓ Branch 1 taken 1300 times.
19456 if (is_in_current_region(screen))
1165 1300 handle_screen_load_trigger(create_screen_handles_one(get_scr(screen)));
1166 19456 }
1167 152 }
1168 34667 else handle_screen_load_trigger(create_screen_handles_one(get_scr(hero_screen)));
1169 34819 }
1170
1171 15800 static void apply_state_changes_to_screen(mapscr& scr, int32_t map, int32_t screen, int32_t flags, bool secrets_do_replay_comment)
1172 {
1173 15800 auto screen_handles = create_screen_handles_one(&scr);
1174
1175
3/4
✓ Branch 0 taken 539 times.
✓ Branch 1 taken 15261 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 539 times.
15800 if ((flags & mSECRET) && canPermSecret(cur_dmap, screen))
1176 {
1177 539 reveal_hidden_stairs(&scr, screen, false);
1178 539 bool do_layers = false;
1179 539 bool from_active_screen = false;
1180 539 trigger_secrets_for_screen_internal(screen_handles, do_layers, from_active_screen, -3, secrets_do_replay_comment);
1181 539 }
1182
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 if (flags & mLIGHTBEAM)
1183 {
1184 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
1185 if (rpos_handle.ctype() == cLIGHTTARGET)
1186 {
1187 if (!(rpos_handle.combo().usrflags&cflag1)) //Unlit version
1188 rpos_handle.increment_data();
1189 }
1190 });
1191 }
1192
1193 15800 int lvl = DMaps[cur_dmap].level;
1194 15800 toggle_switches(game->lvlswitches[lvl], true, screen_handles);
1195 15800 toggle_gswitches_load(screen_handles);
1196
1197
2/2
✓ Branch 0 taken 15708 times.
✓ Branch 1 taken 92 times.
15800 if(flags&mLOCKBLOCK) // if special stuff done before
1198 {
1199 92 remove_screenstatecombos2(screen_handles, false, cLOCKBLOCK, cLOCKBLOCK2);
1200 92 }
1201
1202
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 if(flags&mBOSSLOCKBLOCK) // if special stuff done before
1203 {
1204 remove_screenstatecombos2(screen_handles, false, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
1205 }
1206
1207
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 if(flags&mCHEST) // if special stuff done before
1208 {
1209 remove_screenstatecombos2(screen_handles, false, cCHEST, cCHEST2);
1210 }
1211
1212
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 if(flags&mCHEST) // if special stuff done before
1213 {
1214 remove_screenstatecombos2(screen_handles, false, cLOCKEDCHEST, cLOCKEDCHEST2);
1215 }
1216
1217
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 if(flags&mBOSSCHEST) // if special stuff done before
1218 {
1219 remove_screenstatecombos2(screen_handles, false, cBOSSCHEST, cBOSSCHEST2);
1220 }
1221
1222
1223 15800 int mi = mapind(map, screen);
1224 15800 clear_xdoors_mi(screen_handles, mi);
1225 15800 clear_xstatecombos_mi(screen_handles, mi);
1226
1227 15800 handle_screen_load_trigger(screen_handles);
1228 15800 }
1229
1230 53194 std::optional<mapscr> load_temp_mapscr_and_apply_secrets(int32_t map, int32_t screen, int32_t layer, bool secrets, bool secrets_do_replay_comment)
1231 {
1232
2/4
✓ Branch 0 taken 53194 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53194 times.
53194 if (map < 0 || screen < 0)
1233 return std::nullopt;
1234
1235 53194 const mapscr* source = get_canonical_scr(map, screen);
1236
2/2
✓ Branch 0 taken 40960 times.
✓ Branch 1 taken 12234 times.
53194 if (!source->is_valid())
1237 12234 return std::nullopt;
1238
1239
2/2
✓ Branch 0 taken 8308 times.
✓ Branch 1 taken 32652 times.
40960 if (layer >= 0)
1240 {
1241
2/2
✓ Branch 0 taken 25160 times.
✓ Branch 1 taken 7492 times.
32652 if (source->layermap[layer] <= 0)
1242 25160 return std::nullopt;
1243
1244 7492 source = get_canonical_scr(source->layermap[layer] - 1, source->layerscreen[layer]);
1245
1/2
✓ Branch 0 taken 7492 times.
✗ Branch 1 not taken.
7492 if (!source->is_valid())
1246 return std::nullopt;
1247 7492 }
1248
1249
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 int flags = secrets ? game->maps[mapind(map, screen)] : 0;
1250 15800 mapscr scr = *source;
1251
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15800 times.
15800 apply_state_changes_to_screen(scr, map, screen, flags, secrets_do_replay_comment);
1252
1253 15800 return scr;
1254 53194 }
1255
1256 27203 static int32_t MAPCOMBO3_impl(int32_t map, int32_t screen, int32_t layer, int32_t pos, bool secrets)
1257 {
1258
2/4
✓ Branch 0 taken 27203 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 27203 times.
27203 if (map < 0 || screen < 0) return 0;
1259
1260
2/4
✓ Branch 0 taken 27203 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 27203 times.
27203 if(pos>175 || pos < 0)
1261 return 0;
1262
1263 // TODO: consider caching this (invalidate on any modification via scripting, or anything
1264 // `apply_state_changes_to_screen` checks).
1265
4/5
✓ Branch 0 taken 4976 times.
✓ Branch 1 taken 22227 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4976 times.
✓ Branch 4 taken 22227 times.
32179 if (auto s = load_temp_mapscr_and_apply_secrets(map, screen, layer, secrets))
1266 4976 return s->data[pos];
1267
1268 22227 return 0;
1269 27203 }
1270
1271 // Read from the current temporary screens or, if (map, screen) is not loaded,
1272 // load that screen and apply the relevant secrets before evaluating the combo at that position.
1273 137736708 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets)
1274 {
1275 DCHECK_LAYER_NEG1_INDEX(layer);
1276 DCHECK(map >= 0 && screen >= 0);
1277
1278
2/2
✓ Branch 0 taken 137709505 times.
✓ Branch 1 taken 27203 times.
137736708 if (is_in_current_region(map, screen)) return MAPCOMBO2(layer, x, y);
1279
1280 // Screen is not in the current region, so we have to load and trigger some secrets.
1281 27203 int pos = COMBOPOS(x, y);
1282 27203 return MAPCOMBO3_impl(map, screen, layer, pos, secrets);
1283 137736708 }
1284
1285 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, rpos_t rpos, bool secrets)
1286 {
1287 DCHECK_LAYER_NEG1_INDEX(layer);
1288 DCHECK(map >= 0 && screen >= 0);
1289 DCHECK(is_valid_rpos(rpos));
1290
1291 if (is_in_current_region(map, screen)) return MAPCOMBO(get_rpos_handle(rpos, layer + 1));
1292
1293 // Screen is not currently loaded, so we have to load and trigger some secrets.
1294 return MAPCOMBO3_impl(map, screen, layer, RPOS_TO_POS(rpos), secrets);
1295 }
1296
1297 int32_t MAPCSET2(int32_t layer,int32_t x,int32_t y)
1298 {
1299 DCHECK_LAYER_NEG1_INDEX(layer);
1300 if (!is_in_world_bounds(x, y))
1301 return 0;
1302 if (layer == -1) return MAPCSET(x, y);
1303
1304 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1305 if (!rpos_handle.scr->is_valid()) return 0;
1306
1307 return rpos_handle.cset();
1308 }
1309
1310 98920838 int32_t MAPFLAG2(int32_t layer,int32_t x,int32_t y)
1311 {
1312 DCHECK_LAYER_NEG1_INDEX(layer);
1313
3/4
✓ Branch 0 taken 1894252 times.
✓ Branch 1 taken 97026586 times.
✓ Branch 2 taken 1894252 times.
✗ Branch 3 not taken.
98920838 if (!get_qr(qr_BUGGED_LAYERED_FLAGS) && (!is_in_world_bounds(x, y)))
1314 return 0;
1315
2/2
✓ Branch 0 taken 81313609 times.
✓ Branch 1 taken 17607229 times.
98920838 if (layer == -1) return MAPFLAG(x, y);
1316
1317 81313609 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1318
2/2
✓ Branch 0 taken 63007039 times.
✓ Branch 1 taken 18306570 times.
81313609 if (!rpos_handle.scr->is_valid()) return 0;
1319
1320 18306570 return rpos_handle.sflag();
1321 98920838 }
1322
1323 2518104 int32_t COMBOTYPE2(int32_t layer,int32_t x,int32_t y)
1324 {
1325
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2518104 times.
2518104 if(layer < 1)
1326 {
1327
2/2
✓ Branch 0 taken 5036208 times.
✓ Branch 1 taken 2518104 times.
7554312 for (int32_t i = layer+1; i <= 1; ++i)
1328 {
1329
2/2
✓ Branch 0 taken 4212456 times.
✓ Branch 1 taken 823752 times.
5036208 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1330 {
1331
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4212456 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4212456 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1332 4212456 }
1333 else
1334 {
1335
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 823752 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
823752 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1336 }
1337 5036208 }
1338 2518104 }
1339
1/2
✓ Branch 0 taken 2518104 times.
✗ Branch 1 not taken.
2518104 if(layer==-1) return COMBOTYPE(x,y);
1340
1341 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1342 if (!rpos_handle.scr->is_valid()) return 0;
1343
1344 return rpos_handle.ctype();
1345 2518104 }
1346
1347 // Returns the flag for the combo at the given position.
1348 // This is also known as an "inherent flag".
1349 97151985 int32_t MAPCOMBOFLAG2(int32_t layer,int32_t x,int32_t y)
1350 {
1351 DCHECK_LAYER_NEG1_INDEX(layer);
1352
2/2
✓ Branch 0 taken 288 times.
✓ Branch 1 taken 97151697 times.
97151985 if (!is_in_world_bounds(x, y))
1353 288 return 0;
1354
2/2
✓ Branch 0 taken 81255084 times.
✓ Branch 1 taken 15896613 times.
97151697 if (layer == -1) return MAPCOMBOFLAG(x, y);
1355
1356 81255084 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1357
2/2
✓ Branch 0 taken 63016952 times.
✓ Branch 1 taken 18238132 times.
81255084 if (!rpos_handle.scr->is_valid()) return 0;
1358
1359 18238132 return rpos_handle.cflag();
1360 97151985 }
1361
1362 11626863 bool HASFLAG(int32_t flag, int32_t layer, rpos_t rpos)
1363 {
1364 DCHECK_LAYER_ZERO_INDEX(layer);
1365 11626863 auto rpos_handle = get_rpos_handle(rpos, layer);
1366
2/2
✓ Branch 0 taken 6436480 times.
✓ Branch 1 taken 5190383 times.
11626863 if (!rpos_handle.scr->is_valid()) return false;
1367
2/2
✓ Branch 0 taken 4565 times.
✓ Branch 1 taken 5185818 times.
5190383 if (rpos_handle.sflag() == flag) return true;
1368
2/2
✓ Branch 0 taken 37705 times.
✓ Branch 1 taken 5148113 times.
5185818 if (rpos_handle.cflag() == flag) return true;
1369 5148113 return false;
1370 11626863 }
1371
1372 1697065 bool HASFLAG_ANY(int32_t flag, rpos_t rpos)
1373 {
1374 DCHECK(is_valid_rpos(rpos));
1375
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1697065 times.
1697065 if (rpos > region_max_rpos) return false;
1376
1377
2/2
✓ Branch 0 taken 11626863 times.
✓ Branch 1 taken 1654795 times.
13281658 for(auto q = 0; q < 7; ++q)
1378 {
1379
2/2
✓ Branch 0 taken 42270 times.
✓ Branch 1 taken 11584593 times.
11626863 if(HASFLAG(flag, q, rpos))
1380 42270 return true;
1381 11584593 }
1382 1654795 return false;
1383 1697065 }
1384
1385 const char *screenstate_string[16] =
1386 {
1387 "Door Up", "Door Down", "Door Left", "Door Right", "Item", "Special Item", "No Return",
1388 "Temporary No Return", "Lock Blocks", "Boss Lock Blocks", "Chests", "Locked Chests",
1389 "Boss Locked Chests", "Secrets", "Visited", "Light Beams"
1390 };
1391
1392 34860 void eventlog_mapflags()
1393 {
1394 34860 std::ostringstream oss;
1395
1396 34860 int mi = mapind(cur_map, home_screen);
1397
1/2
✓ Branch 0 taken 34860 times.
✗ Branch 1 not taken.
34860 word g = game->maps[mi] &0x3FFF;
1398
1399
2/4
✓ Branch 0 taken 34860 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 34860 times.
✗ Branch 3 not taken.
34860 oss << fmt::format("Screen ({}, {:02X})", cur_map+1, home_screen);
1400
2/2
✓ Branch 0 taken 7057 times.
✓ Branch 1 taken 27803 times.
34860 if(g) // Main States
1401 {
1402 static const int order[] =
1403 {
1404 mSECRET, mITEM, mSPECIALITEM, mLOCKBLOCK, mBOSSLOCKBLOCK,
1405 mCHEST, mLOCKEDCHEST, mBOSSCHEST,
1406 mDOOR_UP, mDOOR_DOWN, mDOOR_LEFT, mDOOR_RIGHT,
1407 mNEVERRET, mTMPNORET
1408 };
1409
1410
1/2
✓ Branch 0 taken 7057 times.
✗ Branch 1 not taken.
7057 oss << " [";
1411 7057 bool comma = false;
1412
2/2
✓ Branch 0 taken 7057 times.
✓ Branch 1 taken 98798 times.
105855 for(int fl : order)
1413 {
1414
2/2
✓ Branch 0 taken 8976 times.
✓ Branch 1 taken 89822 times.
98798 if(!(g&fl))
1415 89822 continue;
1416 8976 byte ind = byte(log2(double(fl)));
1417
2/2
✓ Branch 0 taken 1919 times.
✓ Branch 1 taken 7057 times.
8976 if(comma)
1418
1/2
✓ Branch 0 taken 1919 times.
✗ Branch 1 not taken.
1919 oss << ", ";
1419
1/2
✓ Branch 0 taken 8976 times.
✗ Branch 1 not taken.
8976 oss << screenstate_string[ind];
1420 8976 comma = true;
1421 }
1422
1/2
✓ Branch 0 taken 7057 times.
✗ Branch 1 not taken.
7057 oss << "]";
1423 7057 }
1424
3/4
✓ Branch 0 taken 34860 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 34822 times.
34860 if(game->xstates[mi]) // ExStates
1425 {
1426
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 oss << " Ex[";
1427 38 bool comma = false;
1428
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 1216 times.
1254 for(byte fl = 0; fl < 32; ++fl)
1429 {
1430
3/4
✓ Branch 0 taken 1216 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 44 times.
✓ Branch 3 taken 1172 times.
1216 if(game->xstates[mi] & (1<<fl))
1431 {
1432
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 38 times.
44 if(comma)
1433
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 oss << ", ";
1434
1/2
✓ Branch 0 taken 44 times.
✗ Branch 1 not taken.
44 oss << int(fl);
1435 44 comma = true;
1436 44 }
1437 1216 }
1438
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 oss << "]";
1439 38 }
1440 { // ExDoors
1441
2/2
✓ Branch 0 taken 34860 times.
✓ Branch 1 taken 139440 times.
174300 for(int q = 0; q < 4; ++q)
1442 {
1443 139440 bool comma = false;
1444
3/4
✓ Branch 0 taken 139440 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 139438 times.
✓ Branch 3 taken 2 times.
139440 if(auto v = game->xdoors[mi][q])
1445 {
1446
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(comma)
1447 oss << ",";
1448
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 else oss << " ExDoor";
1449
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 oss << "[" << dirstr[q];
1450
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 16 times.
18 for(int fl = 0; fl < 8; ++fl)
1451
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 3 times.
19 if(v & (1<<fl))
1452
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 oss << " " << int(fl);
1453
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 oss << "]";
1454 2 comma = true;
1455 2 }
1456 139440 }
1457 }
1458
2/4
✓ Branch 0 taken 34860 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 34860 times.
34860 Z_eventlog("%s\n", oss.str().c_str());
1459 34860 }
1460
1461 // set specific flag
1462 5616 void setmapflag(mapscr* scr, int32_t flag)
1463 {
1464
2/2
✓ Branch 0 taken 5603 times.
✓ Branch 1 taken 13 times.
5616 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1465 5616 int mi = mapind(cur_map, scr->screen);
1466 5616 setmapflag_mi(scr, mi, flag);
1467 5616 }
1468 57 void setmapflag_homescr(int32_t flag)
1469 {
1470 57 int mi = mapind(cur_map, home_screen);
1471 57 setmapflag_mi(origin_scr, mi, flag);
1472 57 }
1473 2023 void setmapflag_mi(int32_t mi, int32_t flag)
1474 {
1475 2023 byte cscr = mi&((1<<7)-1);
1476 2023 byte cmap = (mi>>7);
1477 2023 mapscr* scr = origin_scr;
1478
2/2
✓ Branch 0 taken 834 times.
✓ Branch 1 taken 1189 times.
2023 if (is_in_current_region(cmap, cscr))
1479 1189 scr = get_scr(cmap, cscr);
1480
1481 2023 setmapflag_mi(scr, mi, flag);
1482 2023 }
1483
1484 8478 static void log_state_change(int map, int screen, std::string action)
1485 {
1486
6/6
✓ Branch 0 taken 1913 times.
✓ Branch 1 taken 6565 times.
✓ Branch 2 taken 996 times.
✓ Branch 3 taken 917 times.
✓ Branch 4 taken 352 times.
✓ Branch 5 taken 644 times.
8478 if (is_in_current_region(map, screen) || (map == cur_map && screen == home_screen))
1487 6917 Z_eventlog("[Map %d, Screen %02X (current)] %s\n", map + 1, screen, action.c_str());
1488 else
1489 1561 Z_eventlog("[Map %d, Screen %02X] %s\n", map + 1, screen, action.c_str());
1490 8478 }
1491
1492 7696 void setmapflag_mi(mapscr* scr, int32_t mi, int32_t flag)
1493 {
1494 7696 byte cscr = mi&((1<<7)-1);
1495 7696 byte cmap = (mi>>7);
1496
1497 7696 float temp=log2((float)flag);
1498
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7696 times.
7696 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1499
1500
3/4
✓ Branch 0 taken 7696 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1552 times.
✓ Branch 3 taken 6144 times.
7696 if (replay_is_active() && !(game->maps[mi] & flag))
1501
1/2
✓ Branch 0 taken 6144 times.
✗ Branch 1 not taken.
6144 replay_step_comment(fmt::format("map {} scr {} flag {}", cmap, cscr, state_string));
1502 7696 game->maps[mi] |= flag;
1503
1/2
✓ Branch 0 taken 7696 times.
✗ Branch 1 not taken.
7696 log_state_change(cmap, cscr, fmt::format("State set: {}", state_string));
1504
1505
10/10
✓ Branch 0 taken 5457 times.
✓ Branch 1 taken 2239 times.
✓ Branch 2 taken 3616 times.
✓ Branch 3 taken 1841 times.
✓ Branch 4 taken 3031 times.
✓ Branch 5 taken 585 times.
✓ Branch 6 taken 2877 times.
✓ Branch 7 taken 154 times.
✓ Branch 8 taken 13 times.
✓ Branch 9 taken 2480 times.
10189 if(flag==mSECRET||flag==mITEM||flag==mSPECIALITEM||flag==mLOCKBLOCK||
1506
6/6
✓ Branch 0 taken 2830 times.
✓ Branch 1 taken 47 times.
✓ Branch 2 taken 2685 times.
✓ Branch 3 taken 145 times.
✓ Branch 4 taken 2493 times.
✓ Branch 5 taken 192 times.
2877 flag==mBOSSLOCKBLOCK||flag==mCHEST||flag==mBOSSCHEST||flag==mLOCKEDCHEST)
1507 {
1508 5216 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1509 5216 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1510
1511 5216 std::vector<int32_t> done;
1512
2/2
✓ Branch 0 taken 5101 times.
✓ Branch 1 taken 115 times.
5216 bool looped = (nmap==cmap+1 && nscr==cscr);
1513
1514
6/6
✓ Branch 0 taken 538 times.
✓ Branch 1 taken 5164 times.
✓ Branch 2 taken 52 times.
✓ Branch 3 taken 486 times.
✓ Branch 4 taken 486 times.
✓ Branch 5 taken 5216 times.
5702 while((nmap!=0) && !looped && !(nscr>=128))
1515 {
1516
5/6
✓ Branch 0 taken 364 times.
✓ Branch 1 taken 122 times.
✓ Branch 2 taken 364 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 171 times.
✓ Branch 5 taken 193 times.
486 if((scr->nocarry&flag)!=flag && !(game->maps[((nmap-1)<<7)+nscr] & flag))
1517 {
1518
2/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
193 log_state_change(nmap, nscr, "State change carried over");
1519
2/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
193 if (replay_is_active())
1520
2/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
193 replay_step_comment(fmt::format("map {} scr {} flag {} carry", nmap, nscr, state_string));
1521
1/2
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
193 game->maps[((nmap-1)<<7)+nscr] |= flag;
1522 193 }
1523
1524 486 cmap=nmap;
1525 486 cscr=nscr;
1526 486 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1527 486 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1528
1529
2/2
✓ Branch 0 taken 1480 times.
✓ Branch 1 taken 486 times.
1966 for(auto it = done.begin(); it != done.end(); it++)
1530 {
1531
2/2
✓ Branch 0 taken 1428 times.
✓ Branch 1 taken 52 times.
1480 if(*it == ((nmap-1)<<7)+nscr)
1532 52 looped = true;
1533 1480 }
1534
1535
1/2
✓ Branch 0 taken 486 times.
✗ Branch 1 not taken.
486 done.push_back(((nmap-1)<<7)+nscr);
1536 }
1537 5216 }
1538 7696 }
1539
1540 void unsetmapflag_home(int32_t flag, bool anyflag)
1541 {
1542 int mi = mapind(cur_map, home_screen);
1543 unsetmapflag_mi(origin_scr, mi, flag, anyflag);
1544 }
1545
1546 void unsetmapflag(mapscr* scr, int32_t flag, bool anyflag)
1547 {
1548 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1549 int mi = mapind(cur_map, scr->screen);
1550 unsetmapflag_mi(scr, mi, flag, anyflag);
1551 }
1552
1553 471 void unsetmapflag_mi(int32_t mi, int32_t flag, bool anyflag)
1554 {
1555 471 byte cscr = mi&((1<<7)-1);
1556 471 byte cmap = (mi>>7);
1557 471 mapscr* scr = origin_scr;
1558
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if (is_in_current_region(cmap, cscr))
1559 11 scr = get_scr(cmap, cscr);
1560
1561 471 unsetmapflag_mi(scr, mi, flag, anyflag);
1562 471 }
1563
1564 471 void unsetmapflag_mi(mapscr* scr, int32_t mi, int32_t flag, bool anyflag)
1565 {
1566 471 byte cscr = mi&((1<<7)-1);
1567 471 byte cmap = (mi>>7);
1568
1569
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if(anyflag)
1570 460 game->maps[mi] &= ~flag;
1571
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 else if(flag==mITEM || flag==mSPECIALITEM)
1572 {
1573 if(!(scr->flags4&fNOITEMRESET))
1574 game->maps[mi] &= ~flag;
1575 }
1576 11 else game->maps[mi] &= ~flag;
1577
1578 471 float temp=log2((float)flag);
1579
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1580
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 log_state_change(cmap, cscr, fmt::format("State unset: {}", state_string));
1581
1582
5/10
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 460 times.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 11 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
471 if(flag==mSECRET||flag==mITEM||flag==mSPECIALITEM||flag==mLOCKBLOCK||
1583
4/6
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 5 times.
11 flag==mBOSSLOCKBLOCK||flag==mCHEST||flag==mBOSSCHEST||flag==mLOCKEDCHEST)
1584 {
1585 471 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1586 471 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1587
1588 471 std::vector<int32_t> done;
1589
2/2
✓ Branch 0 taken 466 times.
✓ Branch 1 taken 5 times.
471 bool looped = (nmap==cmap+1 && nscr==cscr);
1590
1591
6/6
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 465 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 84 times.
✓ Branch 4 taken 84 times.
✓ Branch 5 taken 471 times.
555 while((nmap!=0) && !looped && !(nscr>=128))
1592 {
1593
4/6
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 84 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
✓ Branch 5 taken 72 times.
84 if((scr->nocarry&flag)!=flag && (game->maps[((nmap-1)<<7)+nscr] & flag))
1594 {
1595
2/4
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
72 log_state_change(nmap, nscr, "State change carried over");
1596
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 game->maps[((nmap-1)<<7)+nscr] &= ~flag;
1597 72 }
1598
1599 84 cmap=nmap;
1600 84 cscr=nscr;
1601 84 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1602 84 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1603
1604
2/2
✓ Branch 0 taken 546 times.
✓ Branch 1 taken 84 times.
630 for(std::vector<int32_t>::iterator it = done.begin(); it != done.end(); it++)
1605 {
1606
2/2
✓ Branch 0 taken 540 times.
✓ Branch 1 taken 6 times.
546 if(*it == ((nmap-1)<<7)+nscr)
1607 6 looped = true;
1608 546 }
1609
1610
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 done.push_back(((nmap-1)<<7)+nscr);
1611 }
1612 471 }
1613 471 }
1614
1615 44186722 bool getmapflag(int32_t screen, int32_t flag)
1616 {
1617
2/2
✓ Branch 0 taken 1164399 times.
✓ Branch 1 taken 43022323 times.
44186722 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1618 44186722 return (game->maps[mi] & flag) != 0;
1619 }
1620 162340 bool getmapflag(mapscr* scr, int32_t flag)
1621 {
1622 162340 return getmapflag(scr->screen, flag);
1623 }
1624
1625 60 void setxmapflag(int32_t screen, uint32_t flag)
1626 {
1627
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60 times.
60 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1628 60 setxmapflag_mi(mi, flag);
1629 60 }
1630 62 void setxmapflag_mi(int32_t mi, uint32_t flag)
1631 {
1632
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 41 times.
62 if(game->xstates[mi] & flag) return;
1633 41 byte cscr = mi&((1<<7)-1);
1634 41 byte cmap = (mi>>7);
1635
1636 41 byte temp=(byte)log2((double)flag);
1637
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 log_state_change(cmap, cscr, fmt::format("ExtraState set: {}", temp));
1638
1639 41 game->xstates[mi] |= flag;
1640 62 }
1641 2 void unsetxmapflag(int32_t screen, uint32_t flag)
1642 {
1643
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1644 2 unsetxmapflag_mi(mi, flag);
1645 2 }
1646 2 void unsetxmapflag_mi(int32_t mi, uint32_t flag)
1647 {
1648
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(!(game->xstates[mi] & flag)) return;
1649 1 byte cscr = mi&((1<<7)-1);
1650 1 byte cmap = (mi>>7);
1651 1 byte temp=(byte)log2((double)flag);
1652
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 log_state_change(cmap, cscr, fmt::format("ExtraState unset: {}", temp));
1653 1 game->xstates[mi] &= ~flag;
1654 2 }
1655 34 bool getxmapflag(int32_t screen, uint32_t flag)
1656 {
1657
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
34 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1658 34 return getxmapflag_mi(mi, flag);
1659 }
1660 471496368 bool getxmapflag_mi(int32_t mi, uint32_t flag)
1661 {
1662 471496368 return (game->xstates[mi] & flag) != 0;
1663 }
1664
1665 4 void setxdoor_mi(uint mi, uint dir, uint ind, bool state)
1666 {
1667
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
4 if(mi > game->xdoors.size() || dir > 3 || ind > 8)
1668 return;
1669
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(!(game->xdoors[mi][dir] & (1<<ind)) == !state)
1670 return;
1671
1672
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 SETFLAG(game->xdoors[mi][dir], 1<<ind, state);
1673
1674 4 int cscr = mi % MAPSCRSNORMAL;
1675 4 int cmap = mi / MAPSCRSNORMAL;
1676
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (state)
1677
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] set", dirstr[dir], ind));
1678 else
1679 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] unset", dirstr[dir], ind));
1680 4 }
1681 471496329 bool getxdoor_mi(uint mi, uint dir, uint ind)
1682 {
1683
3/6
✓ Branch 0 taken 471496329 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 471496329 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 471496329 times.
471496329 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1684 return false;
1685 471496329 return (game->xdoors[mi][dir] & (1<<ind));
1686 471496329 }
1687 9 bool getxdoor(int32_t screen, uint dir, uint ind)
1688 {
1689 9 int mi = mapind(cur_map, screen);
1690 9 return getxdoor_mi(mi,dir,ind);
1691 }
1692
1693 401 void set_doorstate_mi(uint mi, uint dir)
1694 {
1695
1/2
✓ Branch 0 taken 401 times.
✗ Branch 1 not taken.
401 if(dir >= 4)
1696 return;
1697 401 setmapflag_mi(mi, mDOOR_UP << dir);
1698
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 400 times.
401 if(auto di = nextscr_mi(mi, dir))
1699 400 setmapflag_mi(*di, mDOOR_UP << oppositeDir[dir]);
1700 401 }
1701 401 void set_doorstate(uint screen, uint dir)
1702 {
1703 401 int mi = mapind(cur_map, screen);
1704 401 set_doorstate_mi(mi, dir);
1705 401 }
1706
1707 2 void set_xdoorstate_mi(uint mi, uint dir, uint ind, bool state)
1708 {
1709
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1710 return;
1711 2 setxdoor_mi(mi, dir, ind, state);
1712
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(auto di = nextscr_mi(mi, dir))
1713 2 setxdoor_mi(*di, oppositeDir[dir], ind, state);
1714 2 }
1715
1716 2 void set_xdoorstate(int32_t screen,uint dir, uint ind, bool state)
1717 {
1718 2 int mi = mapind(cur_map, screen);
1719 2 set_xdoorstate_mi(mi, dir, ind, state);
1720 2 }
1721
1722 57 int32_t WARPCODE(int32_t dmap,int32_t screen,int32_t dw)
1723 // returns: -1 = not a warp screen
1724 // 0+ = warp screen code ( high byte=dmap, low byte=scr )
1725 {
1726 57 const mapscr *scr = get_canonical_scr(DMaps[dmap].map, screen);
1727
1728
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(scr->room!=rWARP)
1729 return -1;
1730
1731 57 int32_t ring=scr->catchall;
1732 57 int32_t size=QMisc.warp[ring].size;
1733
1734
1/2
✓ Branch 0 taken 57 times.
✗ Branch 1 not taken.
57 if(size==0)
1735 return -2;
1736
1737 57 int32_t index=-1;
1738
1739
2/2
✓ Branch 0 taken 289 times.
✓ Branch 1 taken 57 times.
346 for(int32_t i=0; i<size; i++)
1740
6/6
✓ Branch 0 taken 230 times.
✓ Branch 1 taken 59 times.
✓ Branch 2 taken 173 times.
✓ Branch 3 taken 57 times.
✓ Branch 4 taken 173 times.
✓ Branch 5 taken 57 times.
289 if(dmap==QMisc.warp[ring].dmap[i] && screen==
1741 346 (QMisc.warp[ring].scr[i] + DMaps[dmap].xoff))
1742 57 index=i;
1743
1744
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(index==-1)
1745 return -3;
1746
1747 57 index = (index+dw)%size;
1748 57 return (QMisc.warp[ring].dmap[index] << 8) + QMisc.warp[ring].scr[index];
1749 57 }
1750
1751 14779693 void update_combo_cycling()
1752 {
1753 14779693 auto& combo_cache = combo_caches::can_cycle;
1754
1755 static int32_t newdata[176];
1756 static int32_t newcset[176];
1757 static bool initialized=false;
1758
1759 // Just a simple bit of optimization
1760
2/2
✓ Branch 0 taken 14779383 times.
✓ Branch 1 taken 310 times.
14779693 if(!initialized)
1761 {
1762
2/2
✓ Branch 0 taken 54560 times.
✓ Branch 1 taken 310 times.
54870 for(int32_t i=0; i<176; i++)
1763 {
1764 54560 newdata[i]=-1;
1765 54560 newcset[i]=-1;
1766 54560 }
1767
1768 310 initialized=true;
1769 310 }
1770
1771 14779693 std::set<uint16_t> restartanim;
1772
1773
1/2
✓ Branch 0 taken 14779693 times.
✗ Branch 1 not taken.
29948754 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
1774 15169061 int screen = scr->screen;
1775 int32_t x;
1776
1777
2/2
✓ Branch 0 taken 2669754736 times.
✓ Branch 1 taken 15169061 times.
2684923797 for(int32_t i=0; i<176; i++)
1778 {
1779 2669754736 x=scr->data[i];
1780 2669754736 auto& mini_cmb = combo_cache.minis[x];
1781
2/2
✓ Branch 0 taken 3273932 times.
✓ Branch 1 taken 2666480804 times.
2669754736 if (!mini_cmb.can_cycle)
1782 2666480804 continue;
1783
1784 3273932 newcombo const& cmb = combobuf[x];
1785
1786 //time to restart
1787
4/4
✓ Branch 0 taken 902694 times.
✓ Branch 1 taken 2371238 times.
✓ Branch 2 taken 474434 times.
✓ Branch 3 taken 428260 times.
3273932 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1788 {
1789 428260 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1790
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428260 times.
428260 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1791 428260 newdata[i] = c;
1792
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 428240 times.
428260 if(!(cmb.animflags & AF_CYCLENOCSET))
1793
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428240 times.
428240 newcset[i] = cycle_under ? scr->undercset : cmb.nextcset;
1794
1795
2/2
✓ Branch 0 taken 427216 times.
✓ Branch 1 taken 1044 times.
428260 if(combobuf[c].animflags & AF_CYCLE)
1796 {
1797 1044 restartanim.insert(c);
1798 1044 }
1799 428260 }
1800 3273932 }
1801
1802 15169061 int rpos_base = (int)POS_TO_RPOS(0, region_scr_x, region_scr_y);
1803
2/2
✓ Branch 0 taken 2669754736 times.
✓ Branch 1 taken 15169061 times.
2684923797 for(int32_t i=0; i<176; i++)
1804 {
1805
2/2
✓ Branch 0 taken 428260 times.
✓ Branch 1 taken 2669326476 times.
2669754736 if(newdata[i]==-1)
1806 2669326476 continue;
1807
1808 428260 rpos_t rpos = (rpos_t)(rpos_base + i);
1809 428260 rpos_handle_t rpos_handle = {scr, screen, 0, rpos, i};
1810 428260 screen_combo_modify_preroutine(rpos_handle);
1811 428260 scr->data[i]=newdata[i];
1812
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 428240 times.
428260 if(newcset[i]>-1)
1813 428240 scr->cset[i]=newcset[i];
1814 428260 screen_combo_modify_postroutine(rpos_handle);
1815
1816 428260 newdata[i]=-1;
1817 428260 newcset[i]=-1;
1818 428260 }
1819
1820 15169061 word c = scr->numFFC();
1821
2/2
✓ Branch 0 taken 15169061 times.
✓ Branch 1 taken 453640195 times.
468809256 for(word i=0; i<c; i++)
1822 {
1823 453640195 ffcdata& ffc = scr->ffcs[i];
1824 453640195 auto& mini_cmb = combo_cache.minis[ffc.data];
1825
2/2
✓ Branch 0 taken 4173 times.
✓ Branch 1 taken 453636022 times.
453640195 if (!mini_cmb.can_cycle)
1826 453636022 continue;
1827
1828 4173 newcombo const& cmb = combobuf[ffc.data];
1829
1830 //time to restart
1831
4/4
✓ Branch 0 taken 611 times.
✓ Branch 1 taken 3562 times.
✓ Branch 2 taken 503 times.
✓ Branch 3 taken 108 times.
4173 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1832 {
1833 108 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1834
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1835 108 zc_ffc_set(ffc, c);
1836
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 if(!(cmb.animflags & AF_CYCLENOCSET))
1837
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 ffc.cset = cycle_under ? scr->undercset : cmb.nextcset;
1838
1839
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 60 times.
108 if(combobuf[ffc.data].animflags & AF_CYCLE)
1840 {
1841 60 restartanim.insert(ffc.data);
1842 60 }
1843 108 }
1844 4173 }
1845
1846
2/2
✓ Branch 0 taken 8418399 times.
✓ Branch 1 taken 6750662 times.
15169061 if(get_qr(qr_CMBCYCLELAYERS))
1847 {
1848
2/2
✓ Branch 0 taken 40503972 times.
✓ Branch 1 taken 6750662 times.
47254634 for(int32_t j=1; j<=6; j++)
1849 {
1850 40503972 mapscr* layer_scr = get_scr_layer_valid(screen, j);
1851
2/2
✓ Branch 0 taken 10894349 times.
✓ Branch 1 taken 29609623 times.
40503972 if (!layer_scr)
1852 29609623 continue;
1853
1854
2/2
✓ Branch 0 taken 1917405424 times.
✓ Branch 1 taken 10894349 times.
1928299773 for(int32_t i=0; i<176; i++)
1855 {
1856 1917405424 x=layer_scr->data[i];
1857 1917405424 auto& mini_cmb = combo_cache.minis[x];
1858
2/2
✓ Branch 0 taken 2230074 times.
✓ Branch 1 taken 1915175350 times.
1917405424 if (!mini_cmb.can_cycle)
1859 1915175350 continue;
1860
1861 2230074 newcombo const& cmb = combobuf[x];
1862
1863 //time to restart
1864
4/4
✓ Branch 0 taken 48416 times.
✓ Branch 1 taken 2181658 times.
✓ Branch 2 taken 37483 times.
✓ Branch 3 taken 10933 times.
2230074 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1865 {
1866 10933 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1867
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10933 times.
10933 auto c = cycle_under ? layer_scr->undercombo : cmb.nextcombo;
1868 10933 newdata[i] = c;
1869
2/2
✓ Branch 0 taken 69 times.
✓ Branch 1 taken 10864 times.
10933 if(!(cmb.animflags & AF_CYCLENOCSET))
1870
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10864 times.
10864 newcset[i] = cycle_under ? layer_scr->undercset : cmb.nextcset;
1871 69 else newcset[i] = layer_scr->cset[i];
1872
1873
2/2
✓ Branch 0 taken 950 times.
✓ Branch 1 taken 9983 times.
10933 if(combobuf[c].animflags & AF_CYCLE)
1874 {
1875 9983 restartanim.insert(c);
1876 9983 }
1877 10933 }
1878 2230074 }
1879
1880
2/2
✓ Branch 0 taken 1917405424 times.
✓ Branch 1 taken 10894349 times.
1928299773 for (int32_t i=0; i<176; i++)
1881 {
1882
2/2
✓ Branch 0 taken 1917394491 times.
✓ Branch 1 taken 10933 times.
1917405424 if(newdata[i]!=-1)
1883 {
1884 10933 layer_scr->data[i]=newdata[i];
1885
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10933 times.
10933 if(newcset[i]>-1)
1886 10933 layer_scr->cset[i]=newcset[i];
1887 10933 newdata[i]=-1;
1888 10933 newcset[i]=-1;
1889 10933 }
1890 1917405424 }
1891 10894349 }
1892 6750662 }
1893 15169061 });
1894
1895
2/2
✓ Branch 0 taken 14779693 times.
✓ Branch 1 taken 2661 times.
14782354 for (auto i : restartanim)
1896 {
1897 2661 combobuf[i].tile = combobuf[i].o_tile;
1898 2661 combobuf[i].cur_frame=0;
1899 2661 combobuf[i].aclk = 0;
1900
1/2
✓ Branch 0 taken 2661 times.
✗ Branch 1 not taken.
2661 combo_caches::drawing.refresh(i);
1901 }
1902 14779693 }
1903
1904 1209946585 bool iswater_type(int32_t type)
1905 {
1906 // return type==cOLD_WATER || type==cSWIMWARP || type==cDIVEWARP || type==cDIVEWARPB || type==cDIVEWARPC || type==cDIVEWARPD || type==cSWIMWARPB || type==cSWIMWARPC || type==cSWIMWARPD;
1907 1209946585 return (combo_class_buf[type].water!=0);
1908 }
1909
1910 bool iswater(int32_t combo)
1911 {
1912 return iswater_type(combobuf[combo].type) && !DRIEDLAKE;
1913 }
1914 1135408 int32_t iswaterexzq(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck)
1915 {
1916 1135408 return iswaterex(combo, map, screen, layer, x, y, secrets, fullcheck, LayerCheck);
1917 }
1918
1919 // (x, y) are world coordinates
1920 58744589 int32_t iswaterex_z3(int32_t combo, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero, optional<combined_handle_t>* out_handle)
1921 {
1922
8/8
✓ Branch 0 taken 58698438 times.
✓ Branch 1 taken 46151 times.
✓ Branch 2 taken 58658106 times.
✓ Branch 3 taken 40332 times.
✓ Branch 4 taken 58591360 times.
✓ Branch 5 taken 66746 times.
✓ Branch 6 taken 59577 times.
✓ Branch 7 taken 58531783 times.
58744589 if (x<0 || x>=world_w || y<0 || y>=world_h)
1923 212806 return false;
1924
1925 58531783 return iswaterex(combo, cur_map, cur_screen, layer, x, y, secrets, fullcheck, LayerCheck, ShallowCheck, hero, out_handle);
1926 58744589 }
1927
1928 97205049 int32_t iswaterex(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero, optional<combined_handle_t>* out_handle)
1929 {
1930 DCHECK_LAYER_NEG1_INDEX(layer);
1931 //Honestly, fullcheck is kinda useless... I made this function back when I thought it was checking the entire combo and not just a glorified x/y value.
1932 //Fullcheck makes no sense to ever be on, but hey I guess it's here in case you ever need it...
1933
1934 //Oh hey, Zoras might actually need it. Nevermind, this had a use!
1935
2/2
✓ Branch 0 taken 57355583 times.
✓ Branch 1 taken 39849466 times.
97205049 if (get_qr(qr_SMARTER_WATER))
1936 {
1937
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 57355583 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
57355583 if (DRIEDLAKE) return 0;
1938
5/6
✓ Branch 0 taken 19560102 times.
✓ Branch 1 taken 37795481 times.
✓ Branch 2 taken 6518562 times.
✓ Branch 3 taken 13041540 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6518562 times.
57355583 if (LayerCheck && (get_qr(qr_WATER_ON_LAYER_1) || get_qr(qr_WATER_ON_LAYER_2))) //LayerCheck is a bit dumber, but it lets me add this QR without having to replace all calls, again.
1939 {
1940
2/2
✓ Branch 0 taken 37777960 times.
✓ Branch 1 taken 12368210 times.
50146170 for (int32_t m = layer; m <= 1; m++)
1941 {
1942
5/6
✓ Branch 0 taken 24736420 times.
✓ Branch 1 taken 13041540 times.
✓ Branch 2 taken 12368210 times.
✓ Branch 3 taken 12368210 times.
✓ Branch 4 taken 12368210 times.
✗ Branch 5 not taken.
50146170 if (m < 0 || m == 0 && get_qr(qr_WATER_ON_LAYER_1)
1943
1/2
✓ Branch 0 taken 12368210 times.
✗ Branch 1 not taken.
24736420 || m == 1 && get_qr(qr_WATER_ON_LAYER_2))
1944 {
1945 37777960 int32_t checkwater = iswaterex(combo, map, screen, m, x, y, secrets, fullcheck, false, ShallowCheck);
1946
2/2
✓ Branch 0 taken 37104630 times.
✓ Branch 1 taken 673330 times.
37777960 if (checkwater > 0)
1947 {
1948
2/2
✓ Branch 0 taken 673272 times.
✓ Branch 1 taken 58 times.
673330 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(x, y, m+1);
1949 673330 return checkwater;
1950 }
1951 37104630 }
1952 37104630 }
1953 12368210 return 0;
1954 }
1955 else
1956 {
1957
2/2
✓ Branch 0 taken 44328716 times.
✓ Branch 1 taken 42139889 times.
86468605 for(int32_t i=(fullcheck?3:0); i>=0; i--)
1958 {
1959 44328716 int32_t tx2=((i&2)<<2)+x;
1960 44328716 int32_t ty2=((i&1)<<3)+y;
1961 44328716 int32_t b = i; //Originally b was not needed and I read off i, but then I added the boolean for fullcheck.
1962 //In which case it's just easier to change b if fullcheck is false instead of changing i and potentially screwing up the for loop.
1963
2/2
✓ Branch 0 taken 21673 times.
✓ Branch 1 taken 44307043 times.
44328716 if (!fullcheck)
1964 {
1965 44307043 tx2 = x;
1966 44307043 ty2 = y;
1967
2/2
✓ Branch 0 taken 24875722 times.
✓ Branch 1 taken 19431321 times.
44307043 if(tx2&8) b+=2;
1968
2/2
✓ Branch 0 taken 20524614 times.
✓ Branch 1 taken 23782429 times.
44307043 if(ty2&8) b+=1;
1969 44307043 }
1970
2/2
✓ Branch 0 taken 94775306 times.
✓ Branch 1 taken 43484483 times.
138259789 for (int32_t m = layer; m <= 1; m++)
1971 {
1972 94775306 newcombo const& cmb = combobuf[MAPCOMBO3(map, screen, m,tx2,ty2, true)];
1973
2/2
✓ Branch 0 taken 17735727 times.
✓ Branch 1 taken 77039579 times.
94775306 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1974 {
1975
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 17735727 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
17735727 if (cmb.type == cBRIDGE && !(cmb.walk&(1<<b)))
1976 {
1977 return 0;
1978 }
1979 17735727 }
1980 else
1981 {
1982
4/4
✓ Branch 0 taken 179102 times.
✓ Branch 1 taken 76860477 times.
✓ Branch 2 taken 51152 times.
✓ Branch 3 taken 127950 times.
77039579 if (cmb.type == cBRIDGE && (cmb.walk&(0x10<<b)))
1983 {
1984 127950 return 0;
1985 }
1986 }
1987
2/2
✓ Branch 0 taken 17735727 times.
✓ Branch 1 taken 76911629 times.
94647356 if (get_qr(qr_NO_SOLID_SWIM))
1988 {
1989
8/14
✓ Branch 0 taken 51152 times.
✓ Branch 1 taken 76860477 times.
✓ Branch 2 taken 51152 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 716283 times.
✓ Branch 5 taken 76144194 times.
✓ Branch 6 taken 3461 times.
✓ Branch 7 taken 712822 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 3461 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
76911629 if ((cmb.type != cBRIDGE || (!get_qr(qr_OLD_BRIDGE_COMBOS) && !(cmb.walk&(0x10<<b)))) && (cmb.walk&(1<<b)) && !((cmb.usrflags&cflag4) && cmb.type == cWATER && (cmb.walk&(0x10<<b)) && ShallowCheck))
1990 {
1991 716283 return 0;
1992 }
1993 76195346 }
1994
3/6
✓ Branch 0 taken 320336 times.
✓ Branch 1 taken 93610737 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 320336 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
93931073 if (iswater_type(cmb.type) && (cmb.walk&(1<<b)) && ((cmb.usrflags&cflag3) || (cmb.usrflags&cflag4)
1995 || (hero && current_item(itype_flippers) < cmb.attribytes[0])
1996 || (hero && ((cmb.usrflags&cflag1) && !(itemsbuf[current_item_id(itype_flippers)].flags & item_flag3)))))
1997 {
1998 if (!(ShallowCheck && (cmb.walk&(1<<b)) && (cmb.usrflags&cflag4))) return 0;
1999 }
2000 93931073 }
2001
2002 131351049 auto found_ffc_not_water = find_ffc([&](const ffc_handle_t& ffc_handle) {
2003
2/2
✓ Branch 0 taken 87338701 times.
✓ Branch 1 taken 527865 times.
87866566 if (ffcIsAt(ffc_handle, tx2, ty2))
2004 {
2005 527865 auto ty = ffc_handle.ctype();
2006
4/6
✓ Branch 0 taken 527865 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 144225 times.
✓ Branch 3 taken 383640 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 144225 times.
527865 if(!combo_class_buf[ty].water && !(ShallowCheck && ty == cSHALLOWWATER))
2007 527865 return true;
2008 }
2009
2010 87338701 return false;
2011 87866566 });
2012
2/2
✓ Branch 0 taken 42956618 times.
✓ Branch 1 taken 527865 times.
43484483 if (found_ffc_not_water) return 0;
2013
2014
2/2
✓ Branch 0 taken 14673 times.
✓ Branch 1 taken 42941945 times.
42956618 if(!i)
2015 {
2016 127956725 auto found_ffc_water = find_ffc([&](const ffc_handle_t& ffc_handle) {
2017
1/2
✓ Branch 0 taken 85014780 times.
✗ Branch 1 not taken.
85014780 if (ffcIsAt(ffc_handle, tx2, ty2))
2018 {
2019 auto ty = ffc_handle.ctype();
2020 if(combo_class_buf[ty].water || (ShallowCheck && ty == cSHALLOWWATER))
2021 return true;
2022 }
2023
2024 85014780 return false;
2025 85014780 });
2026
1/2
✓ Branch 0 taken 42941945 times.
✗ Branch 1 not taken.
42941945 if (found_ffc_water)
2027 {
2028 if(out_handle) *out_handle = *found_ffc_water;
2029 return found_ffc_water->data();
2030 }
2031 42941945 }
2032
2033 42956618 int32_t checkcombo = MAPCOMBO3(map, screen, layer, tx2, ty2, secrets);
2034
2/2
✓ Branch 0 taken 42912124 times.
✓ Branch 1 taken 44494 times.
42956618 if (!(combobuf[checkcombo].walk&(1<<(b+4)))) return 0;
2035
7/12
✓ Branch 0 taken 42631519 times.
✓ Branch 1 taken 280605 times.
✓ Branch 2 taken 10830537 times.
✓ Branch 3 taken 31800982 times.
✓ Branch 4 taken 10352353 times.
✓ Branch 5 taken 478184 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 10352353 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
42912124 if (iswater_type(combobuf[checkcombo].type)||(ShallowCheck && (combobuf[checkcombo].type == cSHALLOWWATER || (iswater_type(combobuf[checkcombo].type) && (combobuf[checkcombo].walk&(1<<b)) && (combobuf[checkcombo].usrflags&cflag4)))))
2036 {
2037
2/2
✓ Branch 0 taken 1227 times.
✓ Branch 1 taken 757562 times.
758789 if (i == 0)
2038 {
2039
2/2
✓ Branch 0 taken 757553 times.
✓ Branch 1 taken 9 times.
757562 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(tx2, ty2, layer+1);
2040 757562 return checkcombo;
2041 }
2042 1227 }
2043 42154562 }
2044 42139889 return 0;
2045 }
2046 }
2047 else
2048 {
2049 39849466 int32_t b = 0;
2050
2/2
✓ Branch 0 taken 20636413 times.
✓ Branch 1 taken 19213053 times.
39849466 if(x&8) b+=2;
2051
2/2
✓ Branch 0 taken 15456485 times.
✓ Branch 1 taken 24392981 times.
39849466 if(y&8) b+=1;
2052
1/2
✓ Branch 0 taken 39849466 times.
✗ Branch 1 not taken.
39849466 if (get_qr(qr_NO_SOLID_SWIM))
2053 {
2054 if (combobuf[combo].walk&(1<<b))
2055 {
2056 return 0;
2057 }
2058 }
2059
1/2
✓ Branch 0 taken 39849466 times.
✗ Branch 1 not taken.
39849466 if (!(combobuf[combo].walk&(1<<(b+4)))) return 0;
2060
8/8
✓ Branch 0 taken 38150906 times.
✓ Branch 1 taken 1698560 times.
✓ Branch 2 taken 167945 times.
✓ Branch 3 taken 37982961 times.
✓ Branch 4 taken 2129 times.
✓ Branch 5 taken 1782338 times.
✓ Branch 6 taken 163774 times.
✓ Branch 7 taken 161691 times.
39849466 if((iswater_type(combobuf[combo].type) || (ShallowCheck && combobuf[combo].type == cSHALLOWWATER)) && !DRIEDLAKE)
2061 {
2062
2/2
✓ Branch 0 taken 1943999 times.
✓ Branch 1 taken 30 times.
1944029 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(x, y, 0); //NOTE: This is only correct assuming 'combo' is 'MAPCOMBO(x,y)'
2063 1944029 return combo;
2064 }
2065 38146735 return 0;
2066 }
2067 97446347 }
2068
2069 326 bool isdamage_type(int32_t type)
2070 {
2071
1/2
✓ Branch 0 taken 326 times.
✗ Branch 1 not taken.
326 switch(type)
2072 {
2073 case cDAMAGE1: case cDAMAGE2: case cDAMAGE3: case cDAMAGE4:
2074 case cDAMAGE5: case cDAMAGE6: case cDAMAGE7:
2075 return true;
2076 }
2077 326 return false;
2078 326 }
2079
2080 2569346943 bool ispitfall_type(int32_t type)
2081 {
2082 2569346943 return combo_class_buf[type].pit != 0;
2083 }
2084
2085 2569346943 bool ispitfall(int32_t combo)
2086 {
2087 2569346943 return ispitfall_type(combobuf[combo].type);
2088 }
2089
2090 278127950 bool ispitfall(int32_t x, int32_t y)
2091 {
2092
2/2
✓ Branch 0 taken 1456039 times.
✓ Branch 1 taken 276671911 times.
278127950 if(int32_t c = MAPFFCOMBO(x,y))
2093 {
2094 1456039 return ispitfall(c) ? true : false;
2095 }
2096 276671911 int32_t c = MAPCOMBOL(2,x,y);
2097
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 276671911 times.
276671911 if(ispitfall(c)) return true;
2098
2/2
✓ Branch 0 taken 263560767 times.
✓ Branch 1 taken 13111144 times.
276671911 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2099 {
2100
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 263560767 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
263560767 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return false;
2101 263560767 }
2102 else
2103 {
2104
3/4
✓ Branch 0 taken 2780 times.
✓ Branch 1 taken 13108364 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2780 times.
13111144 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return false;
2105 }
2106 276669131 c = MAPCOMBOL(1,x,y);
2107
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 276669107 times.
276669131 if(ispitfall(c)) return true;
2108
2109
2/2
✓ Branch 0 taken 263560767 times.
✓ Branch 1 taken 13108340 times.
276669107 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2110 {
2111
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 263560767 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
263560767 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return false;
2112 263560767 }
2113 else
2114 {
2115
4/4
✓ Branch 0 taken 13072 times.
✓ Branch 1 taken 13095268 times.
✓ Branch 2 taken 8777 times.
✓ Branch 3 taken 4295 times.
13108340 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return false;
2116 }
2117 276660330 c = MAPCOMBO(x,y);
2118
2/2
✓ Branch 0 taken 70747 times.
✓ Branch 1 taken 276589583 times.
276660330 if(ispitfall(c)) return true;
2119 276589583 return false;
2120 278127950 }
2121
2122 585542306 int32_t getpitfall(int32_t x, int32_t y) //Return the highest-layer active pit combo at the given position
2123 {
2124
2/2
✓ Branch 0 taken 9281019 times.
✓ Branch 1 taken 576261287 times.
585542306 if(int32_t c = MAPFFCOMBO(x,y))
2125 {
2126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9281019 times.
9281019 return ispitfall(c) ? c : 0;
2127 }
2128 576261287 int32_t c = MAPCOMBOL(2,x,y);
2129
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 576261287 times.
576261287 if(ispitfall(c)) return c;
2130
2131
2/2
✓ Branch 0 taken 532722485 times.
✓ Branch 1 taken 43538802 times.
576261287 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2132 {
2133
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 532722485 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
532722485 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return 0;
2134 532722485 }
2135 else
2136 {
2137
3/4
✓ Branch 0 taken 35747 times.
✓ Branch 1 taken 43503055 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 35747 times.
43538802 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return 0;
2138 }
2139 576225540 c = MAPCOMBOL(1,x,y);
2140
2/2
✓ Branch 0 taken 278 times.
✓ Branch 1 taken 576225262 times.
576225540 if(ispitfall(c)) return c;
2141
2142
2/2
✓ Branch 0 taken 532722485 times.
✓ Branch 1 taken 43502777 times.
576225262 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2143 {
2144
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 532722485 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
532722485 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return 0;
2145 532722485 }
2146 else
2147 {
2148
4/4
✓ Branch 0 taken 144357 times.
✓ Branch 1 taken 43358420 times.
✓ Branch 2 taken 103729 times.
✓ Branch 3 taken 40628 times.
43502777 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return 0;
2149 }
2150 576121533 c = MAPCOMBO(x,y);
2151
2/2
✓ Branch 0 taken 176844 times.
✓ Branch 1 taken 575944689 times.
576121533 if(ispitfall(c)) return c;
2152 575944689 return 0;
2153 585542306 }
2154 51 optional<combined_handle_t> get_pitfall_handle(int32_t x, int32_t y) //Return the highest-layer active pit combo handle at the given position
2155 {
2156
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if(int32_t c = MAPFFCOMBO(x,y))
2157 {
2158 return ispitfall(c) ? getFFCAt(x,y) : nullopt;
2159 }
2160 51 int32_t c = MAPCOMBOL(2,x,y);
2161
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 2);
2162
2163
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 45 times.
51 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2164 {
2165
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1))
2166 return nullopt;
2167 6 }
2168 else
2169 {
2170
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
45 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1))
2171 return nullopt;
2172 }
2173 51 c = MAPCOMBOL(1,x,y);
2174
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 1);
2175
2176
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 45 times.
51 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2177 {
2178
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0))
2179 return nullopt;
2180 6 }
2181 else
2182 {
2183
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
45 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0))
2184 return nullopt;
2185 }
2186 51 c = MAPCOMBO(x,y);
2187
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 0);
2188 return nullopt;
2189 51 }
2190 5426640 bool check_icy(newcombo const& cmb, int type)
2191 {
2192
2/2
✓ Branch 0 taken 5426475 times.
✓ Branch 1 taken 165 times.
5426640 if(cmb.type != cICY)
2193 5426475 return false;
2194
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 165 times.
165 switch(type)
2195 {
2196 case ICY_BLOCK:
2197 return cmb.usrflags&cflag1;
2198 case ICY_PLAYER:
2199 165 return cmb.usrflags&cflag2;
2200 }
2201 return false;
2202 5426640 }
2203 1811404 int get_icy(int x, int y, int type)
2204 {
2205 1811404 int32_t c = MAPCOMBOL(2,x,y);
2206
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1811404 times.
1811404 if(check_icy(combobuf[c], type)) return c;
2207
2208 1811404 int screen = get_screen_for_world_xy(x, y);
2209
2210 1811404 mapscr* scr = get_scr_layer_valid(screen, 2);
2211
2/2
✓ Branch 0 taken 430769 times.
✓ Branch 1 taken 1380635 times.
1811404 if (scr)
2212 {
2213
2/2
✓ Branch 0 taken 516 times.
✓ Branch 1 taken 1380119 times.
1380635 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2214 {
2215
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 516 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
516 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2216 516 }
2217 else
2218 {
2219
3/4
✓ Branch 0 taken 3048 times.
✓ Branch 1 taken 1377071 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3048 times.
1380119 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2220 }
2221 1377587 }
2222 1808356 c = MAPCOMBOL(1,x,y);
2223
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1808356 times.
1808356 if(check_icy(combobuf[c], type)) return c;
2224
2225 1808356 scr = get_scr_layer_valid(screen, 1);
2226
2/2
✓ Branch 0 taken 73612 times.
✓ Branch 1 taken 1734744 times.
1808356 if (scr)
2227 {
2228
2/2
✓ Branch 0 taken 1934 times.
✓ Branch 1 taken 1732810 times.
1734744 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2229 {
2230
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1934 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1934 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2231 1934 }
2232 else
2233 {
2234
3/4
✓ Branch 0 taken 1641 times.
✓ Branch 1 taken 1731169 times.
✓ Branch 2 taken 1641 times.
✗ Branch 3 not taken.
1732810 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2235 }
2236 1733103 }
2237 1806715 c = MAPCOMBO(x,y);
2238
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1806715 times.
1806715 if(check_icy(combobuf[c], type)) return c;
2239 1806715 return 0;
2240 1811404 }
2241
2242 13049028 static bool checkSV(int32_t x, int32_t y, int32_t flag)
2243 {
2244
8/8
✓ Branch 0 taken 13042230 times.
✓ Branch 1 taken 6798 times.
✓ Branch 2 taken 13033364 times.
✓ Branch 3 taken 8866 times.
✓ Branch 4 taken 13021732 times.
✓ Branch 5 taken 11632 times.
✓ Branch 6 taken 428468 times.
✓ Branch 7 taken 12593264 times.
13049028 if(x<0 || x>=world_w || y<0 || y>=world_h)
2245 455764 return false;
2246
2247 12593264 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
2248
2/4
✓ Branch 0 taken 12593264 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12593264 times.
12593264 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2249 return true;
2250
2251 12593264 change_rpos_handle_layer(rpos_handle, 1);
2252
2/2
✓ Branch 0 taken 7565554 times.
✓ Branch 1 taken 5027710 times.
12593264 if (rpos_handle.scr->is_valid())
2253
3/4
✓ Branch 0 taken 5027710 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3279 times.
✓ Branch 3 taken 5024431 times.
5027710 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2254 3279 return true;
2255
2256 12589985 change_rpos_handle_layer(rpos_handle, 2);
2257
2/2
✓ Branch 0 taken 10876848 times.
✓ Branch 1 taken 1713137 times.
12589985 if (rpos_handle.scr->is_valid())
2258
2/4
✓ Branch 0 taken 1713137 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1713137 times.
1713137 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2259 return true;
2260
2261 12589985 return false;
2262 13049028 }
2263
2264 6588676 bool isSVLadder(int32_t x, int32_t y)
2265 {
2266 6588676 return checkSV(x, y, mfSIDEVIEWLADDER);
2267 }
2268
2269 6460352 bool isSVPlatform(int32_t x, int32_t y)
2270 {
2271 6460352 return checkSV(x, y, mfSIDEVIEWPLATFORM);
2272 }
2273
2274 6460352 bool checkSVLadderPlatform(int32_t x, int32_t y)
2275 {
2276
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6460352 times.
✓ Branch 2 taken 6458555 times.
✓ Branch 3 taken 1797 times.
6460352 return isSVPlatform(x,y) || (isSVLadder(x,y) && !isSVLadder(x,y-16));
2277 }
2278
2279 1637 bool isstepable(int32_t combo) //can use ladder on it
2280 {
2281
2/2
✓ Branch 0 taken 1631 times.
✓ Branch 1 taken 6 times.
1637 if(combo_class_buf[combobuf[combo].type].ladder_pass) return true;
2282
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(combo_class_buf[combobuf[combo].type].pit)
2283 {
2284 if(combobuf[combo].usrflags&cflag4)
2285 {
2286 int32_t ldrid = current_item_id(itype_ladder);
2287 return (ldrid > -1 && itemsbuf[ldrid].flags & item_flag1);
2288 }
2289 }
2290 6 return false;
2291 1637 }
2292
2293 32780 bool isHSGrabbable(newcombo const& cmb)
2294 {
2295
2/2
✓ Branch 0 taken 373 times.
✓ Branch 1 taken 32407 times.
32780 if(cmb.type == cHSGRAB) return true;
2296 32407 return cmb.genflags & cflag1;
2297 32780 }
2298
2299 954 bool isSwitchHookable(newcombo const& cmb)
2300 {
2301
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 822 times.
954 if(cmb.type == cSWITCHHOOK) return true;
2302 822 return cmb.genflags & cflag2;
2303 954 }
2304
2305 61401 bool check_hshot(int32_t layer, int32_t x, int32_t y, bool switchhook, rpos_t *out_rpos, ffcdata **out_ffc)
2306 {
2307 61401 rpos_t cpos = rpos_t::None;
2308
2/2
✓ Branch 0 taken 64592 times.
✓ Branch 1 taken 125993 times.
61401 if(out_rpos)
2309 {
2310 125993 int32_t id = MAPCOMBO2(layer-1,x,y);
2311
2/2
✓ Branch 0 taken 28634 times.
✓ Branch 1 taken 97359 times.
125993 if(id > 0)
2312 {
2313 97359 newcombo const& cmb = combobuf[id];
2314
4/4
✓ Branch 0 taken 32738 times.
✓ Branch 1 taken 64621 times.
✓ Branch 2 taken 32296 times.
✓ Branch 3 taken 32325 times.
97359 cpos = (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb)) ? COMBOPOS_REGION(x,y) : rpos_t::None;
2315 32767 }
2316 61401 }
2317
2318 125993 ffcdata* ffc = nullptr;
2319
4/4
✓ Branch 0 taken 28389 times.
✓ Branch 1 taken 97604 times.
✓ Branch 2 taken 24996 times.
✓ Branch 3 taken 3393 times.
125993 if (out_ffc && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2320 {
2321 10359 for_some_ffcs([&](const ffc_handle_t& ffc_handle) {
2322
2/2
✓ Branch 0 taken 6853 times.
✓ Branch 1 taken 113 times.
6966 if (ffcIsAt(ffc_handle, x, y))
2323 {
2324 113 auto& cmb = ffc_handle.combo();
2325
4/4
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 71 times.
✓ Branch 2 taken 35 times.
✓ Branch 3 taken 36 times.
113 if (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb))
2326 {
2327 77 ffc = ffc_handle.ffc;
2328 77 return false;
2329 }
2330 36 }
2331 6889 return true;
2332 6896 });
2333 3393 }
2334
2335
4/4
✓ Branch 0 taken 61401 times.
✓ Branch 1 taken 64592 times.
✓ Branch 2 taken 442 times.
✓ Branch 3 taken 60959 times.
125993 if (out_rpos && cpos != rpos_t::None) *out_rpos = cpos;
2336
4/4
✓ Branch 0 taken 28389 times.
✓ Branch 1 taken 97604 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 28382 times.
125993 if (out_ffc && ffc) *out_ffc = ffc;
2337
2/2
✓ Branch 0 taken 65034 times.
✓ Branch 1 taken 60959 times.
125993 return (cpos != rpos_t::None || ffc);
2338 }
2339
2340 5195 bool ishookshottable(int32_t bx, int32_t by)
2341 {
2342
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5195 times.
5195 if(!_walkflag(bx,by,1))
2343 return true;
2344
2345
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5187 times.
5195 if (collide_object(bx, by, 1, 1))
2346 8 return false;
2347
2348 5187 bool ret = true;
2349
2/2
✓ Branch 0 taken 15561 times.
✓ Branch 1 taken 1900 times.
17461 for(int32_t i=2; i>=0; i--)
2350 {
2351 15561 int32_t c = MAPCOMBO2(i-1,bx,by);
2352 15561 int32_t t = combobuf[c].type;
2353
2354
6/6
✓ Branch 0 taken 5187 times.
✓ Branch 1 taken 10374 times.
✓ Branch 2 taken 3853 times.
✓ Branch 3 taken 1334 times.
✓ Branch 4 taken 1900 times.
✓ Branch 5 taken 1953 times.
15561 if(i == 0 && (t == cHOOKSHOTONLY || t == cLADDERHOOKSHOT)) return true;
2355
2356
3/4
✓ Branch 0 taken 11321 times.
✓ Branch 1 taken 953 times.
✓ Branch 2 taken 953 times.
✗ Branch 3 not taken.
13227 bool dried = (iswater_type(t) && DRIEDLAKE);
2357
2358 12274 int32_t b=1;
2359
2360
2/2
✓ Branch 0 taken 6109 times.
✓ Branch 1 taken 6165 times.
12274 if(bx&8) b<<=2;
2361
2362
2/2
✓ Branch 0 taken 3841 times.
✓ Branch 1 taken 8433 times.
12274 if(by&8) b<<=1;
2363
2364
7/8
✓ Branch 0 taken 2094 times.
✓ Branch 1 taken 10180 times.
✓ Branch 2 taken 2094 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1115 times.
✓ Branch 5 taken 979 times.
✓ Branch 6 taken 75 times.
✓ Branch 7 taken 904 times.
12274 if(combobuf[c].walk&b && !dried && !(combo_class_buf[t].ladder_pass && t!=cLADDERONLY) && t!=cHOOKSHOTONLY)
2365 904 ret = false;
2366 12274 }
2367
2368 1900 return ret;
2369 5195 }
2370
2371 10110 bool reveal_hidden_stairs(mapscr *s, int32_t screen, bool redraw)
2372 {
2373
4/4
✓ Branch 0 taken 9531 times.
✓ Branch 1 taken 579 times.
✓ Branch 2 taken 9531 times.
✓ Branch 3 taken 579 times.
10110 if((s->stairx || s->stairy) && s->secretcombo[sSTAIRS])
2374 {
2375 579 int pos = COMBOPOS(s->stairx,s->stairy);
2376 579 s->data[pos] = s->secretcombo[sSTAIRS];
2377 579 s->cset[pos] = s->secretcset[sSTAIRS];
2378 579 s->sflag[pos] = s->secretflag[sSTAIRS];
2379
2380
2/2
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 323 times.
579 if (redraw)
2381 {
2382 768 auto [x, y] = translate_screen_coordinates_to_world(screen, s->stairx, s->stairy);
2383 768 putcombo(scrollbuf,x,y,s->data[pos],s->cset[pos]);
2384 256 }
2385
2386 579 return true;
2387 }
2388
2389 9531 return false;
2390 10110 }
2391
2392 51767 screen_handles_t create_screen_handles_one(mapscr* base_scr)
2393 {
2394 DCHECK(base_scr->is_valid());
2395
2396 51767 screen_handles_t screen_handles{};
2397 51767 screen_handles[0] = {base_scr, base_scr, base_scr->screen, 0};
2398 51767 return screen_handles;
2399 }
2400
2401 56531226 screen_handles_t create_screen_handles(mapscr* base_scr)
2402 {
2403 DCHECK(get_scr(base_scr->screen) == base_scr);
2404 DCHECK(base_scr->is_valid());
2405
2406 56531226 int screen = base_scr->screen;
2407 screen_handles_t screen_handles;
2408 56531226 screen_handles[0] = {base_scr, base_scr, screen, 0};
2409
2/2
✓ Branch 0 taken 339187356 times.
✓ Branch 1 taken 56531226 times.
395718582 for (int i = 1; i <= 6; i++)
2410 339187356 screen_handles[i] = {base_scr, get_scr_layer_valid(screen, i), screen, i};
2411 56531226 return screen_handles;
2412 }
2413
2414 106202 bool remove_screenstatecombos2(const screen_handles_t& screen_handles, bool do_layers, int32_t what1, int32_t what2)
2415 {
2416 106202 mapscr* scr = screen_handles[0].scr;
2417 106202 bool didit=false;
2418
2419
2/2
✓ Branch 0 taken 106202 times.
✓ Branch 1 taken 18691552 times.
18797754 for(int32_t i=0; i<176; i++)
2420 {
2421 18691552 newcombo const& cmb = combobuf[scr->data[i]];
2422
2/2
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 18691226 times.
18691552 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2423
4/4
✓ Branch 0 taken 18689693 times.
✓ Branch 1 taken 1533 times.
✓ Branch 2 taken 1102 times.
✓ Branch 3 taken 18688591 times.
18691226 if((cmb.type == what1) || (cmb.type== what2))
2424 {
2425 2635 scr->data[i]++;
2426 2635 didit=true;
2427 2635 }
2428 18691226 }
2429
2430
2/2
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 106110 times.
106202 if (do_layers)
2431 {
2432
2/2
✓ Branch 0 taken 636660 times.
✓ Branch 1 taken 106110 times.
742770 for(int32_t j=1; j<=6; j++)
2433 {
2434 636660 mapscr* layer_scr = screen_handles[j].scr;
2435
2/2
✓ Branch 0 taken 173044 times.
✓ Branch 1 taken 463616 times.
636660 if (!layer_scr) continue;
2436
2437
2/2
✓ Branch 0 taken 30455744 times.
✓ Branch 1 taken 173044 times.
30628788 for(int32_t i=0; i<176; i++)
2438 {
2439 30455744 newcombo const& cmb = combobuf[layer_scr->data[i]];
2440
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30455744 times.
30455744 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2441
4/4
✓ Branch 0 taken 30455661 times.
✓ Branch 1 taken 83 times.
✓ Branch 2 taken 265 times.
✓ Branch 3 taken 30455396 times.
30455744 if((cmb.type== what1) || (cmb.type== what2))
2442 {
2443 348 layer_scr->data[i]++;
2444 348 didit=true;
2445 348 }
2446 30455744 }
2447 173044 }
2448 106110 }
2449
2450 // 'do_layers' also means that this is called on an active temp screen, so update its ffcs.
2451
3/4
✓ Branch 0 taken 20406 times.
✓ Branch 1 taken 85796 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 20406 times.
106202 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && do_layers)
2452 {
2453 20406 word c = scr->numFFC();
2454
2/2
✓ Branch 0 taken 73350 times.
✓ Branch 1 taken 20406 times.
93756 for(word i=0; i<c; i++)
2455 {
2456 73350 ffcdata* ffc = &scr->ffcs[i];
2457 73350 newcombo const& cmb = combobuf[ffc->data];
2458
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73350 times.
73350 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2459
2/4
✓ Branch 0 taken 73350 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 73350 times.
73350 if((cmb.type== what1) || (cmb.type== what2))
2460 {
2461 zc_ffc_modify(*ffc, 1);
2462 didit=true;
2463 }
2464 73350 }
2465 20406 }
2466
2467 106202 return didit;
2468 }
2469
2470 14 bool remove_xstatecombos(const screen_handles_t& screen_handles, byte xflag, bool triggers)
2471 {
2472 14 int screen = screen_handles[0].scr->screen;
2473
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2474 14 return remove_xstatecombos_mi(screen_handles, mi, xflag, triggers);
2475 }
2476 471496334 bool remove_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, byte xflag, bool triggers)
2477 {
2478 471496334 bool didit=false;
2479
2/2
✓ Branch 0 taken 471467476 times.
✓ Branch 1 taken 28858 times.
471496334 if(!getxmapflag_mi(mi, 1<<xflag)) return false;
2480
2481 28858 mapscr* s = screen_handles[0].scr;
2482 28858 int screen = s->screen;
2483 28858 bool is_active_screen = is_in_current_region(s);
2484
2485 24248394 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2486
4/4
✓ Branch 0 taken 24207920 times.
✓ Branch 1 taken 11616 times.
✓ Branch 2 taken 24206112 times.
✓ Branch 3 taken 1808 times.
24219536 if(triggers && force_ex_trigger_any(rpos_handle, xflag))
2487 1808 didit = true;
2488
2/2
✓ Branch 0 taken 63627 times.
✓ Branch 1 taken 24154101 times.
24217728 else switch (rpos_handle.ctype())
2489 {
2490 case cLOCKBLOCK: case cLOCKBLOCK2:
2491 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2492 case cCHEST: case cCHEST2:
2493 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2494 case cBOSSCHEST: case cBOSSCHEST2:
2495 {
2496 63627 auto& cmb = rpos_handle.combo();
2497
2/2
✓ Branch 0 taken 62059 times.
✓ Branch 1 taken 1568 times.
63627 if(!(cmb.usrflags&cflag16)) return; //custom state instead of normal state
2498
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 62030 times.
62059 if(cmb.attribytes[5] == xflag)
2499 {
2500 29 rpos_handle.increment_data();
2501 29 didit=true;
2502 29 }
2503 62059 break;
2504 }
2505 }
2506 24219536 });
2507
2508
4/4
✓ Branch 0 taken 28817 times.
✓ Branch 1 taken 41 times.
✓ Branch 2 taken 19197 times.
✓ Branch 3 taken 9620 times.
28858 if (is_active_screen && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2509 {
2510 19197 word c = s->numFFC();
2511 19197 int screen_index_offset = get_region_screen_offset(screen);
2512
2/2
✓ Branch 0 taken 36840 times.
✓ Branch 1 taken 19197 times.
56037 for (uint8_t i = 0; i < c; i++)
2513 {
2514 36840 auto ffc_handle = *s->getFFCHandle(i, screen_index_offset);
2515 36840 auto& cmb = ffc_handle.combo();
2516
3/4
✓ Branch 0 taken 36840 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 36824 times.
✓ Branch 3 taken 16 times.
36840 if(triggers && force_ex_trigger_ffc_any(ffc_handle, xflag))
2517 16 didit = true;
2518
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36824 times.
36824 else switch(cmb.type)
2519 {
2520 case cLOCKBLOCK: case cLOCKBLOCK2:
2521 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2522 case cCHEST: case cCHEST2:
2523 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2524 case cBOSSCHEST: case cBOSSCHEST2:
2525 {
2526 if(!(cmb.usrflags&cflag16)) continue; //custom state instead of normal state
2527 if(cmb.attribytes[5] == xflag)
2528 {
2529 zc_ffc_modify(*ffc_handle.ffc, 1);
2530 didit=true;
2531 }
2532 break;
2533 }
2534 }
2535 36840 }
2536 19197 }
2537
2538 28858 return didit;
2539 471496334 }
2540
2541 14682263 void clear_xstatecombos(const screen_handles_t& screen_handles, bool triggers)
2542 {
2543 14682263 int screen = screen_handles[0].screen;
2544
2/2
✓ Branch 0 taken 387833 times.
✓ Branch 1 taken 14294430 times.
14682263 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2545 14682263 clear_xstatecombos_mi(screen_handles, mi, triggers);
2546 14682263 }
2547
2548 14734260 void clear_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2549 {
2550
2/2
✓ Branch 0 taken 471496320 times.
✓ Branch 1 taken 14734260 times.
486230580 for (int q = 0; q < 32; ++q)
2551 {
2552 471496320 remove_xstatecombos_mi(screen_handles, mi, q, triggers);
2553 471496320 }
2554 14734260 }
2555
2556 bool remove_xdoors(const screen_handles_t& screen_handles, uint dir, uint ind, bool triggers)
2557 {
2558 int screen = screen_handles[0].screen;
2559 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2560 return remove_xdoors_mi(screen_handles, mi, dir, ind, triggers);
2561 }
2562 471496320 bool remove_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, uint dir, uint ind, bool triggers)
2563 {
2564 471496320 bool didit=false;
2565
2/2
✓ Branch 0 taken 471495007 times.
✓ Branch 1 taken 1313 times.
471496320 if (!getxdoor_mi(mi, dir, ind)) return false;
2566
2567 1313 mapscr* scr = screen_handles[0].scr;
2568 1313 int screen = scr->screen;
2569 1313 bool is_active_screen = is_in_current_region(scr);
2570
2571 925665 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2572
3/4
✓ Branch 0 taken 924352 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 924341 times.
924352 if (triggers && force_ex_door_trigger_any(rpos_handle, dir, ind))
2573 11 didit = true;
2574 else; //future door combo types?
2575 924352 });
2576
2577
2/4
✓ Branch 0 taken 1313 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1313 times.
✗ Branch 3 not taken.
1313 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && is_active_screen)
2578 {
2579 1313 word c = scr->numFFC();
2580 1313 int screen_index_offset = get_region_screen_offset(screen);
2581
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1313 times.
1313 for (uint8_t i = 0; i < c; i++)
2582 {
2583 auto ffc_handle = *scr->getFFCHandle(i, screen_index_offset);
2584 if (triggers && force_ex_door_trigger_ffc_any(ffc_handle, dir, ind))
2585 didit = true;
2586 else; //future door combo types?
2587 }
2588 1313 }
2589
2590 1313 return didit;
2591 471496320 }
2592
2593 14682263 void clear_xdoors(const screen_handles_t& screen_handles, bool triggers)
2594 {
2595 14682263 int screen = screen_handles[0].screen;
2596
2/2
✓ Branch 0 taken 387833 times.
✓ Branch 1 taken 14294430 times.
14682263 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2597 14682263 return clear_xdoors_mi(screen_handles, mi, triggers);
2598 }
2599
2600 14734260 void clear_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2601 {
2602
2/2
✓ Branch 0 taken 58937040 times.
✓ Branch 1 taken 14734260 times.
73671300 for (int dir = 0; dir < 4; ++dir)
2603
2/2
✓ Branch 0 taken 471496320 times.
✓ Branch 1 taken 58937040 times.
530433360 for (int q = 0; q < 8; ++q)
2604 530433360 remove_xdoors_mi(screen_handles, mi, dir, q, triggers);
2605 14734260 }
2606
2607 763 bool remove_lockblocks(const screen_handles_t& screen_handles)
2608 {
2609 763 return remove_screenstatecombos2(screen_handles, true, cLOCKBLOCK, cLOCKBLOCK2);
2610 }
2611
2612 98 bool remove_bosslockblocks(const screen_handles_t& screen_handles)
2613 {
2614 98 return remove_screenstatecombos2(screen_handles, true, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
2615 }
2616
2617 76553 bool remove_chests(const screen_handles_t& screen_handles)
2618 {
2619 76553 return remove_screenstatecombos2(screen_handles, true, cCHEST, cCHEST2);
2620 }
2621
2622 2484 bool remove_lockedchests(const screen_handles_t& screen_handles)
2623 {
2624 2484 return remove_screenstatecombos2(screen_handles, true, cLOCKEDCHEST, cLOCKEDCHEST2);
2625 }
2626
2627 26212 bool remove_bosschests(const screen_handles_t& screen_handles)
2628 {
2629 26212 return remove_screenstatecombos2(screen_handles, true, cBOSSCHEST, cBOSSCHEST2);
2630 }
2631
2632 1384361 void delete_fireball_shooter(const rpos_handle_t& rpos_handle)
2633 {
2634 1384361 int32_t ct=rpos_handle.ctype();
2635
2636
6/6
✓ Branch 0 taken 1383741 times.
✓ Branch 1 taken 620 times.
✓ Branch 2 taken 1383489 times.
✓ Branch 3 taken 252 times.
✓ Branch 4 taken 1383381 times.
✓ Branch 5 taken 108 times.
1384361 if(ct!=cL_STATUE && ct!=cR_STATUE && ct!=cC_STATUE)
2637 1383381 return;
2638
2639 2465 auto [cx, cy] = rpos_handle.xy();
2640
3/4
✓ Branch 0 taken 252 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 620 times.
✓ Branch 3 taken 108 times.
980 switch(ct)
2641 {
2642 case cL_STATUE:
2643 620 cx += 4;
2644 620 cy += 7;
2645 620 break;
2646
2647 case cR_STATUE:
2648 252 cx -= 8;
2649 252 cy -= 1;
2650 252 break;
2651
2652 case cC_STATUE:
2653 108 break;
2654 }
2655
2656
2/2
✓ Branch 0 taken 980 times.
✓ Branch 1 taken 1485 times.
2465 for(int32_t j=0; j<guys.Count(); j++)
2657 {
2658 // Finds the smallest enemy ID
2659
9/10
✓ Branch 0 taken 399 times.
✓ Branch 1 taken 1086 times.
✓ Branch 2 taken 399 times.
✓ Branch 3 taken 1086 times.
✓ Branch 4 taken 346 times.
✓ Branch 5 taken 53 times.
✓ Branch 6 taken 346 times.
✓ Branch 7 taken 53 times.
✓ Branch 8 taken 346 times.
✗ Branch 9 not taken.
2970 if((int32_t(guys.spr(j)->x)==cx)&&(int32_t(guys.spr(j)->y)==cy)&&(guysbuf[(guys.spr(j)->id)&0xFFF].flags & guy_fire))
2660 {
2661 346 guys.del(j);
2662 346 }
2663 1485 }
2664 1384361 }
2665
2666 15 static int32_t findtrigger(int32_t screen)
2667 {
2668 15 int32_t checkflag=0;
2669 15 int32_t ret = 0;
2670
2671 mapscr* screens[7];
2672
2/2
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 15 times.
120 for (int32_t j = 0; j <= 6; j++)
2673 {
2674 105 screens[j] = get_scr_layer_valid(screen, j);
2675 105 }
2676
2677 15 bool sflag = false;
2678
2/2
✓ Branch 0 taken 2640 times.
✓ Branch 1 taken 15 times.
2655 for(word j=0; j<176; j++)
2679 {
2680
2/2
✓ Branch 0 taken 26752 times.
✓ Branch 1 taken 2640 times.
29392 for(int32_t layer = -1; layer < 6; ++layer)
2681 {
2682 26752 mapscr* scr = screens[layer+1];
2683
2/2
✓ Branch 0 taken 16544 times.
✓ Branch 1 taken 10208 times.
26752 if (!scr) continue;
2684
2685
2/2
✓ Branch 0 taken 8272 times.
✓ Branch 1 taken 8272 times.
16544 if(sflag)
2686 8272 checkflag = scr->sflag[j];
2687 else
2688 8272 checkflag = combobuf[scr->data[j]].flag;
2689 16544 sflag = !sflag;
2690
2/2
✓ Branch 0 taken 8272 times.
✓ Branch 1 taken 8272 times.
16544 if (sflag) --layer;
2691
2692
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 16534 times.
16544 switch(checkflag)
2693 {
2694 case mfANYFIRE:
2695 case mfSTRONGFIRE:
2696 case mfMAGICFIRE:
2697 case mfDIVINEFIRE:
2698 case mfARROW:
2699 case mfSARROW:
2700 case mfGARROW:
2701 case mfSBOMB:
2702 case mfBOMB:
2703 case mfBRANG:
2704 case mfMBRANG:
2705 case mfFBRANG:
2706 case mfWANDMAGIC:
2707 case mfREFMAGIC:
2708 case mfREFFIREBALL:
2709 case mfSWORD:
2710 case mfWSWORD:
2711 case mfMSWORD:
2712 case mfXSWORD:
2713 case mfSWORDBEAM:
2714 case mfWSWORDBEAM:
2715 case mfMSWORDBEAM:
2716 case mfXSWORDBEAM:
2717 case mfHOOKSHOT:
2718 case mfWAND:
2719 case mfHAMMER:
2720 case mfSTRIKE:
2721 10 ret += 1;
2722 10 break;
2723 }
2724 16544 }
2725 2640 }
2726
2727 15 return ret;
2728 }
2729
2730 11738 static void log_trigger_secret_reason(TriggerSource source)
2731 {
2732
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 11299 times.
11738 if (source == TriggerSource::Singular)
2733 {
2734 439 Z_eventlog("Restricted Screen Secrets triggered\n");
2735 439 }
2736 else
2737 {
2738 11299 const char* source_str = "";
2739
7/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 7178 times.
✓ Branch 3 taken 856 times.
✓ Branch 4 taken 2733 times.
✓ Branch 5 taken 475 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 52 times.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
11299 switch (source)
2740 {
2741 case TriggerSource::Singular: break;
2742 7178 case TriggerSource::Unspecified: source_str = "unspecified means"; break;
2743 856 case TriggerSource::EnemiesScreenFlag: source_str = "the 'Enemies->Secret' screen flag"; break;
2744 2733 case TriggerSource::SecretsScreenState: source_str = "the 'Secrets' screen state"; break;
2745 475 case TriggerSource::Script: source_str = "a script"; break;
2746 1 case TriggerSource::ItemsSecret: source_str = "Items->Secrets"; break;
2747 52 case TriggerSource::GenericCombo: source_str = "Generic Combo"; break;
2748 4 case TriggerSource::LightTrigger: source_str = "Light Triggers"; break;
2749 case TriggerSource::SCC: source_str = "SCC"; break;
2750 case TriggerSource::CheatTemp: source_str = "Cheat (Temp)"; break;
2751 case TriggerSource::CheatPerm: source_str = "Cheat (Perm)"; break;
2752 }
2753 11299 Z_eventlog("Screen Secrets triggered by %s\n", source_str);
2754 }
2755 11738 }
2756
2757 // single:
2758 // >-1 : the singular triggering combo
2759 // -1: triggered by some other cause
2760 11530 void trigger_secrets_for_screen(TriggerSource source, mapscr* scr, bool high16only, int32_t single)
2761 {
2762 11530 log_trigger_secret_reason(source);
2763
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 11091 times.
11530 if (single < 0)
2764 11091 get_screen_state(scr->screen).triggered_secrets = true;
2765
2766 11530 bool do_replay_comment = true;
2767 11530 bool from_active_screen = true;
2768 11530 trigger_secrets_for_screen_internal(create_screen_handles(scr), from_active_screen, high16only, single, do_replay_comment);
2769
2770 // Respect secret state carryovers for active screens.
2771
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 11091 times.
11530 if (single >= 0) return;
2772 11091 int flag = mSECRET;
2773 11091 int cmap = scr->map;
2774 11091 int cscr = scr->screen;
2775 11091 int nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
2776 11091 int nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
2777
2778 11091 std::vector<int32_t> done;
2779
2/2
✓ Branch 0 taken 10904 times.
✓ Branch 1 taken 187 times.
11091 bool looped = (nmap==cmap+1 && nscr==cscr);
2780
2781
6/6
✓ Branch 0 taken 629 times.
✓ Branch 1 taken 11014 times.
✓ Branch 2 taken 77 times.
✓ Branch 3 taken 552 times.
✓ Branch 4 taken 552 times.
✓ Branch 5 taken 11091 times.
11643 while((nmap!=0) && !looped && !(nscr>=128))
2782 {
2783
9/10
✓ Branch 0 taken 385 times.
✓ Branch 1 taken 167 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 301 times.
✓ Branch 4 taken 74 times.
✓ Branch 5 taken 10 times.
✓ Branch 6 taken 74 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
✓ Branch 9 taken 70 times.
552 if (nmap - 1 == cur_map && is_in_current_region(nscr) && (scr->nocarry&flag)!=flag && !get_screen_state(nscr).triggered_secrets)
2784 {
2785
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
2786
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 trigger_secrets_for_screen_internal(create_screen_handles(get_scr(nscr)), from_active_screen, high16only, single, do_replay_comment);
2787
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 get_screen_state(nscr).triggered_secrets = true;
2788 4 }
2789
2790 552 cmap=nmap;
2791 552 cscr=nscr;
2792 552 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
2793 552 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
2794
2795
2/2
✓ Branch 0 taken 1101 times.
✓ Branch 1 taken 552 times.
1653 for(auto it = done.begin(); it != done.end(); it++)
2796 {
2797
2/2
✓ Branch 0 taken 1024 times.
✓ Branch 1 taken 77 times.
1101 if(*it == ((nmap-1)<<7)+nscr)
2798 77 looped = true;
2799 1101 }
2800
2801
1/2
✓ Branch 0 taken 552 times.
✗ Branch 1 not taken.
552 done.push_back(((nmap-1)<<7)+nscr);
2802 }
2803 11530 }
2804
2805 2437 void trigger_secrets_for_screen(TriggerSource source, int32_t screen, bool high16only, int32_t single)
2806 {
2807 2437 trigger_secrets_for_screen(source, get_scr(screen), high16only, single);
2808 2437 }
2809
2810 18007 void trigger_secrets_for_screen_internal(const screen_handles_t& screen_handles, bool from_active_screen, bool high16only, int32_t single, bool do_replay_comment)
2811 {
2812 18007 mapscr* scr = screen_handles[0].scr;
2813 18007 int screen = scr->screen;
2814
2815 // TODO(replays): No real reason for "do_replay_comment" to exist - I just did not want to update many replays when fixing
2816 // slopes in sideview mode (which required loading nearby screens in loadscr).
2817 // TODO(replays): This should just use `screen`.
2818
3/4
✓ Branch 0 taken 18007 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 539 times.
✓ Branch 3 taken 17468 times.
18007 if (replay_is_active() && do_replay_comment)
2819
4/6
✓ Branch 0 taken 11534 times.
✓ Branch 1 taken 5934 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11534 times.
✓ Branch 4 taken 17468 times.
✗ Branch 5 not taken.
17468 replay_step_comment(fmt::format("trigger secrets scr={}", from_active_screen && scr != special_warp_return_scr ? screen : cur_screen));
2820
2821
2/2
✓ Branch 0 taken 6473 times.
✓ Branch 1 taken 11534 times.
18007 if (from_active_screen)
2822 {
2823 5442998 for_every_combo_in_screen(screen_handles, [&](const auto& handle) {
2824
2/4
✓ Branch 0 taken 5429776 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1688 times.
✗ Branch 3 not taken.
5661701 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
2825 230237 return trig.trigger_flags.get(TRIGFLAG_SECRETSTR);
2826 }, ctrigSECRETS);
2827 5431464 });
2828 11534 }
2829
2830 18007 int32_t ft=0; //Flag trigger?
2831 18007 int32_t msflag=0; // Misc. secret flag
2832
2833
2/2
✓ Branch 0 taken 3169232 times.
✓ Branch 1 taken 18007 times.
3187239 for(int32_t i=0; i<176; i++) //Do the 'trigger flags' (non 16-31)
2834 {
2835
4/4
✓ Branch 0 taken 77264 times.
✓ Branch 1 taken 3091968 times.
✓ Branch 2 taken 439 times.
✓ Branch 3 taken 76825 times.
3169232 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2836
2837 // Remember the misc. secret flag; if triggered, use this instead
2838
4/4
✓ Branch 0 taken 114511 times.
✓ Branch 1 taken 2977896 times.
✓ Branch 2 taken 49462 times.
✓ Branch 3 taken 65049 times.
3092407 if(scr->sflag[i]>=mfSECRETS01 && scr->sflag[i]<=mfSECRETS16)
2839 65049 msflag=sSECRET01+(scr->sflag[i]-mfSECRETS01);
2840
4/4
✓ Branch 0 taken 47230 times.
✓ Branch 1 taken 2980128 times.
✓ Branch 2 taken 46999 times.
✓ Branch 3 taken 231 times.
3027358 else if(combobuf[scr->data[i]].flag>=mfSECRETS01 && combobuf[scr->data[i]].flag<=mfSECRETS16)
2841 231 msflag=sSECRET01+(combobuf[scr->data[i]].flag-mfSECRETS01);
2842 else
2843 3027127 msflag=0;
2844
2845
4/4
✓ Branch 0 taken 921256 times.
✓ Branch 1 taken 2171151 times.
✓ Branch 2 taken 72 times.
✓ Branch 3 taken 921184 times.
3092407 if(!high16only || single>=0)
2846 {
2847 2171223 int32_t newflag = -1;
2848
2849
2/2
✓ Branch 0 taken 4342446 times.
✓ Branch 1 taken 2171223 times.
6513669 for(int32_t iter=0; iter<2; ++iter)
2850 {
2851 4342446 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
2852
2853
2/2
✓ Branch 0 taken 2171223 times.
✓ Branch 1 taken 2171223 times.
4342446 if(iter==1) checkflag=scr->sflag[i]; //Placed
2854
2855 4342446 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2856
2/2
✓ Branch 0 taken 4330212 times.
✓ Branch 1 taken 12234 times.
4342446 if (ft != -1) //Change the combos for the secret
2857 {
2858 // Use misc. secret flag instead if one is present
2859
2/2
✓ Branch 0 taken 12202 times.
✓ Branch 1 taken 32 times.
12234 if(msflag!=0)
2860 32 ft=msflag;
2861
2862 12234 rpos_handle_t rpos_handle;
2863
2/2
✓ Branch 0 taken 6367 times.
✓ Branch 1 taken 5867 times.
12234 if (from_active_screen)
2864 {
2865 5867 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
2866 5867 screen_combo_modify_preroutine(rpos_handle);
2867 5867 }
2868
2869
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12234 times.
12234 if(ft==sSECNEXT)
2870 {
2871 scr->data[i]++;
2872 }
2873 else
2874 {
2875 12234 scr->data[i] = scr->secretcombo[ft];
2876 12234 scr->cset[i] = scr->secretcset[ft];
2877 }
2878 12234 newflag = scr->secretflag[ft];
2879
2880
2/2
✓ Branch 0 taken 6367 times.
✓ Branch 1 taken 5867 times.
12234 if (from_active_screen)
2881 5867 screen_combo_modify_postroutine(rpos_handle);
2882 12234 }
2883 4342446 }
2884
2885
2/2
✓ Branch 0 taken 2158995 times.
✓ Branch 1 taken 12228 times.
2171223 if(newflag >-1) scr->sflag[i] = newflag; //Tiered secret
2886
2887
2/2
✓ Branch 0 taken 13027338 times.
✓ Branch 1 taken 2171223 times.
15198561 for(int32_t j=1; j<=6; j++) //Layers
2888 {
2889 13027338 mapscr* layer_scr = screen_handles[j].scr;
2890
2/2
✓ Branch 0 taken 3185797 times.
✓ Branch 1 taken 9841541 times.
13027338 if (!layer_scr) continue;
2891
2892
3/4
✓ Branch 0 taken 725 times.
✓ Branch 1 taken 3185072 times.
✓ Branch 2 taken 725 times.
✗ Branch 3 not taken.
3185797 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2893
2894 3185797 int32_t newflag2 = -1;
2895
2896 // Remember the misc. secret flag; if triggered, use this instead
2897
4/4
✓ Branch 0 taken 14182 times.
✓ Branch 1 taken 3171615 times.
✓ Branch 2 taken 4773 times.
✓ Branch 3 taken 9409 times.
3185797 if(layer_scr->sflag[i]>=mfSECRETS01 && layer_scr->sflag[i]<=mfSECRETS16)
2898 9409 msflag=sSECRET01+(layer_scr->sflag[i]-mfSECRETS01);
2899
4/4
✓ Branch 0 taken 126931 times.
✓ Branch 1 taken 3049457 times.
✓ Branch 2 taken 126560 times.
✓ Branch 3 taken 371 times.
3176388 else if(combobuf[layer_scr->data[i]].flag>=mfSECRETS01 && combobuf[layer_scr->data[i]].flag<=mfSECRETS16)
2900 371 msflag=sSECRET01+(combobuf[layer_scr->data[i]].flag-mfSECRETS01);
2901 else
2902 3176017 msflag=0;
2903
2904
2/2
✓ Branch 0 taken 6371594 times.
✓ Branch 1 taken 3185797 times.
9557391 for(int32_t iter=0; iter<2; ++iter)
2905 {
2906 6371594 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
2907
2/2
✓ Branch 0 taken 3185797 times.
✓ Branch 1 taken 3185797 times.
6371594 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
2908
2909 6371594 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2910
2/2
✓ Branch 0 taken 6371116 times.
✓ Branch 1 taken 478 times.
6371594 if (ft != -1) //Change the combos for the secret
2911 {
2912 // Use misc. secret flag instead if one is present
2913
2/2
✓ Branch 0 taken 476 times.
✓ Branch 1 taken 2 times.
478 if(msflag!=0)
2914 2 ft=msflag;
2915
2916
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 478 times.
478 if(ft==sSECNEXT)
2917 {
2918 layer_scr->data[i]++;
2919 }
2920 else
2921 {
2922 478 layer_scr->data[i] = layer_scr->secretcombo[ft];
2923 478 layer_scr->cset[i] = layer_scr->secretcset[ft];
2924 }
2925 478 newflag2 = layer_scr->secretflag[ft];
2926 478 int32_t c=layer_scr->data[i];
2927 478 int32_t cs=layer_scr->cset[i];
2928
2929
3/4
✓ Branch 0 taken 406 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 406 times.
✗ Branch 3 not taken.
478 if (from_active_screen && combobuf[c].type==cSPINTILE1) //Surely this means we can have spin tiles on layers 3+? Isn't that bad? ~Joe123
2930 {
2931 auto [offx, offy] = translate_screen_coordinates_to_world(screen, COMBOX(i), COMBOY(i));
2932 addenemy(screen,offx,offy,(cs<<12)+eSPINTILE1,combobuf[c].o_tile+zc_max(1,combobuf[c].frames));
2933 }
2934 478 }
2935 6371594 }
2936
2937
2/2
✓ Branch 0 taken 478 times.
✓ Branch 1 taken 3185319 times.
3185797 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered secret
2938 3185797 }
2939 2171223 }
2940 3092407 }
2941
2942 18007 word c = scr->numFFC();
2943
2/2
✓ Branch 0 taken 506903 times.
✓ Branch 1 taken 18007 times.
524910 for(word i=0; i<c; i++) //FFC 'trigger flags'
2944 {
2945
3/4
✓ Branch 0 taken 492983 times.
✓ Branch 1 taken 13920 times.
✓ Branch 2 taken 13920 times.
✗ Branch 3 not taken.
506903 if(single>=0) if(i+176!=single) continue;
2946
2947
3/4
✓ Branch 0 taken 166605 times.
✓ Branch 1 taken 326378 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 166605 times.
492983 if((!high16only)||(single>=0))
2948 {
2949 //for (int32_t iter=0; iter<1; ++iter) // Only one kind of FFC flag now.
2950 {
2951 326378 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
2952 //No placed flags yet
2953
2954 326378 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2955
2/2
✓ Branch 0 taken 326347 times.
✓ Branch 1 taken 31 times.
326378 if (ft != -1) //Change the ffc's combo
2956 {
2957
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if(ft==sSECNEXT)
2958 {
2959 zc_ffc_modify(scr->ffcs[i], 1);
2960 }
2961 else
2962 {
2963 31 zc_ffc_set(scr->ffcs[i], scr->secretcombo[ft]);
2964 31 scr->ffcs[i].cset = scr->secretcset[ft];
2965 }
2966 31 }
2967 }
2968 326378 }
2969 492983 }
2970
2971
2/2
✓ Branch 0 taken 15610 times.
✓ Branch 1 taken 2397 times.
18007 if(checktrigger) //Hit all triggers->16-31
2972 {
2973 2397 checktrigger=false;
2974
2975
2/2
✓ Branch 0 taken 2388 times.
✓ Branch 1 taken 9 times.
2397 if(scr->flags6&fTRIGGERF1631)
2976 {
2977 9 int32_t tr = findtrigger(screen); //Normal flags
2978
2979
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 4 times.
9 if(tr)
2980 {
2981 5 Z_eventlog("Hit All Triggers->16-31 not fulfilled (%d trigger flag%s remain).\n", tr, tr>1?"s":"");
2982 5 goto endhe;
2983 }
2984 4 }
2985 2392 }
2986
2987
2/2
✓ Branch 0 taken 3168352 times.
✓ Branch 1 taken 18002 times.
3186354 for(int32_t i=0; i<176; i++) // Do the 16-31 secrets
2988 {
2989 //If it's an enemies->secret screen, only do the high 16 if told to
2990 //That way you can have secret and burn/bomb entrance separately
2991 3168352 bool old_enem_secret = get_qr(qr_ENEMIES_SECRET_ONLY_16_31);
2992
6/6
✓ Branch 0 taken 2780624 times.
✓ Branch 1 taken 387728 times.
✓ Branch 2 taken 85184 times.
✓ Branch 3 taken 3083168 times.
✓ Branch 4 taken 19536 times.
✓ Branch 5 taken 65648 times.
3168352 if(((!(old_enem_secret && (scr->flags2&fCLEARSECRET)) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM))
2993 {
2994 3102704 int32_t newflag = -1;
2995
2996
2/2
✓ Branch 0 taken 6205408 times.
✓ Branch 1 taken 3102704 times.
9308112 for(int32_t iter=0; iter<2; ++iter)
2997 {
2998 6205408 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
2999
3000
2/2
✓ Branch 0 taken 3102704 times.
✓ Branch 1 taken 3102704 times.
6205408 if(iter==1) checkflag=scr->sflag[i]; //Placed
3001
3002
4/4
✓ Branch 0 taken 161185 times.
✓ Branch 1 taken 6044223 times.
✓ Branch 2 taken 94853 times.
✓ Branch 3 taken 66332 times.
6205408 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
3003 {
3004 66332 rpos_handle_t rpos_handle;
3005
2/2
✓ Branch 0 taken 9952 times.
✓ Branch 1 taken 56380 times.
66332 if (from_active_screen)
3006 {
3007 56380 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
3008 56380 screen_combo_modify_preroutine(rpos_handle);
3009 56380 }
3010
3011 66332 scr->data[i] = scr->secretcombo[checkflag-16+4];
3012 66332 scr->cset[i] = scr->secretcset[checkflag-16+4];
3013 66332 newflag = scr->secretflag[checkflag-16+4];
3014
3015
2/2
✓ Branch 0 taken 9952 times.
✓ Branch 1 taken 56380 times.
66332 if (from_active_screen)
3016 56380 screen_combo_modify_postroutine(rpos_handle);
3017 66332 }
3018 6205408 }
3019
3020
2/2
✓ Branch 0 taken 3036396 times.
✓ Branch 1 taken 66308 times.
3102704 if(newflag >-1) scr->sflag[i] = newflag; //Tiered flag
3021
3022
2/2
✓ Branch 0 taken 18616224 times.
✓ Branch 1 taken 3102704 times.
21718928 for(int32_t j=1; j<=6; j++) //Layers
3023 {
3024 18616224 mapscr* layer_scr = screen_handles[j].scr;
3025
2/2
✓ Branch 0 taken 4866752 times.
✓ Branch 1 taken 13749472 times.
18616224 if (!layer_scr) continue;
3026
3027 4866752 int32_t newflag2 = -1;
3028
3029
2/2
✓ Branch 0 taken 9733504 times.
✓ Branch 1 taken 4866752 times.
14600256 for(int32_t iter=0; iter<2; ++iter)
3030 {
3031 9733504 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
3032
3033
2/2
✓ Branch 0 taken 4866752 times.
✓ Branch 1 taken 4866752 times.
9733504 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
3034
3035
4/4
✓ Branch 0 taken 151246 times.
✓ Branch 1 taken 9582258 times.
✓ Branch 2 taken 131622 times.
✓ Branch 3 taken 19624 times.
9733504 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
3036 {
3037 19624 layer_scr->data[i] = layer_scr->secretcombo[checkflag-16+4];
3038 19624 layer_scr->cset[i] = layer_scr->secretcset[checkflag-16+4];
3039 19624 newflag2 = layer_scr->secretflag[checkflag-16+4];
3040 19624 }
3041 9733504 }
3042
3043
2/2
✓ Branch 0 taken 4847128 times.
✓ Branch 1 taken 19624 times.
4866752 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered flag
3044 4866752 }
3045 3102704 }
3046 3168352 }
3047
3048
2/2
✓ Branch 0 taken 506743 times.
✓ Branch 1 taken 18002 times.
524745 for(word i=0; i<c; i++) // FFCs
3049 {
3050
6/6
✓ Branch 0 taken 466852 times.
✓ Branch 1 taken 39891 times.
✓ Branch 2 taken 15367 times.
✓ Branch 3 taken 491376 times.
✓ Branch 4 taken 3530 times.
✓ Branch 5 taken 11837 times.
506743 if((!(scr->flags2&fCLEARSECRET) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM)
3051 {
3052 494906 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
3053
3054 //No placed flags yet
3055
4/4
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 494838 times.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 12 times.
494906 if((checkflag > 15)&&(checkflag < 32)) //If we find a flag, change the combo
3056 {
3057
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
12 if (from_active_screen)
3058 9 zc_ffc_set(scr->ffcs[i], scr->secretcombo[checkflag - 16 + 4]);
3059 else
3060 3 scr->ffcs[i].data = scr->secretcombo[checkflag - 16 + 4];
3061 12 scr->ffcs[i].cset = scr->secretcset[checkflag-16+4];
3062 12 }
3063 494906 }
3064 524745 }
3065
3066 endhe:
3067
3068
1/2
✓ Branch 0 taken 18007 times.
✗ Branch 1 not taken.
18007 if (scr->flags4&fDISABLETIME) //Finish timed warp if 'Secrets Disable Timed Warp'
3069 {
3070 if (from_active_screen)
3071 activated_timed_warp = true;
3072 scr->timedwarptics = 0;
3073 }
3074 18007 }
3075
3076 // x,y are world coordinates.
3077 // Returns true if there is a flag (either combo, screen, or ffc) at (x, y).
3078 // Out parameters will be set if the flag is Trigger->Self, which modifies how secrets will be triggered.
3079 13508239 static bool has_flag_trigger(int32_t x, int32_t y, int32_t flag, rpos_t& out_rpos, bool& out_single16)
3080 {
3081
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13508239 times.
13508239 if (!is_in_world_bounds(x, y)) return false;
3082
3083 13508239 bool found_cflag = false;
3084 13508239 bool found_nflag = false;
3085 13508239 bool single16 = false;
3086 13508239 rpos_t rpos = rpos_t::None;
3087
3088
2/2
✓ Branch 0 taken 13506155 times.
✓ Branch 1 taken 94545481 times.
108051636 for (int32_t layer = -1; layer < 6; layer++)
3089 {
3090
2/2
✓ Branch 0 taken 94543397 times.
✓ Branch 1 taken 2084 times.
94545481 if (MAPFLAG2(layer, x, y) == flag)
3091 {
3092 2084 found_nflag = true;
3093 2084 break;
3094 }
3095 94543397 }
3096
3097
2/2
✓ Branch 0 taken 13507935 times.
✓ Branch 1 taken 94556397 times.
108064332 for (int32_t layer = -1; layer < 6; layer++)
3098 {
3099
2/2
✓ Branch 0 taken 94556093 times.
✓ Branch 1 taken 304 times.
94556397 if (MAPCOMBOFLAG2(layer, x, y) == flag)
3100 {
3101 304 found_cflag = true;
3102 304 break;
3103 }
3104 94556093 }
3105
3106
2/2
✓ Branch 0 taken 94557673 times.
✓ Branch 1 taken 13508239 times.
108065912 for (int32_t i=-1; i<6; i++) // Look for Trigger->Self on all layers
3107 {
3108
2/2
✓ Branch 0 taken 94543085 times.
✓ Branch 1 taken 14588 times.
94557673 if (found_nflag) // Trigger->Self (a.k.a Singular) is inherent
3109 {
3110
3/4
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 14476 times.
✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
14588 if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE) && (MAPFLAG2(i, x, y) == flag))
3111 {
3112 112 rpos = COMBOPOS_REGION(x, y);
3113 112 }
3114
3/4
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 14424 times.
✓ Branch 2 taken 52 times.
✗ Branch 3 not taken.
14476 else if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE16) && (MAPFLAG2(i, x, y) == flag))
3115 {
3116 52 rpos = COMBOPOS_REGION(x, y);
3117 52 single16 = true;
3118 52 }
3119 14588 }
3120
3121
2/2
✓ Branch 0 taken 94555545 times.
✓ Branch 1 taken 2128 times.
94557673 if (found_cflag) // Trigger->Self (a.k.a Singular) is non-inherent
3122 {
3123
3/4
✓ Branch 0 taken 255 times.
✓ Branch 1 taken 1873 times.
✓ Branch 2 taken 255 times.
✗ Branch 3 not taken.
2128 if ((MAPFLAG2(i, x, y) == mfSINGLE) && (MAPCOMBOFLAG2(i, x, y) == flag))
3124 {
3125 255 rpos = COMBOPOS_REGION(x, y);
3126 255 }
3127
3/4
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 1853 times.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
1873 else if ((MAPFLAG2(i, x, y) == mfSINGLE16) && (MAPCOMBOFLAG2(i, x, y) == flag))
3128 {
3129 20 rpos = COMBOPOS_REGION(x, y);
3130 20 single16 = true;
3131 20 }
3132 2128 }
3133 94557673 }
3134
3135 13508239 out_rpos = rpos;
3136 13508239 out_single16 = single16;
3137
4/4
✓ Branch 0 taken 13506155 times.
✓ Branch 1 taken 2084 times.
✓ Branch 2 taken 13505853 times.
✓ Branch 3 taken 302 times.
13508239 return found_nflag || found_cflag || MAPFFCOMBOFLAG(x,y) == flag;
3138 13508239 }
3139
3140 4457867 bool trigger_secrets_if_flag(int32_t x, int32_t y, int32_t flag, bool setflag)
3141 {
3142
8/8
✓ Branch 0 taken 4457627 times.
✓ Branch 1 taken 240 times.
✓ Branch 2 taken 4455730 times.
✓ Branch 3 taken 1897 times.
✓ Branch 4 taken 4455210 times.
✓ Branch 5 taken 520 times.
✓ Branch 6 taken 952 times.
✓ Branch 7 taken 4454258 times.
4457867 if (x < -16 || y < -16 || x >= world_w || y >= world_h) return false;
3143
3144 4454258 mapscr* scr = NULL;
3145 4454258 int32_t screen = -1;
3146 4454258 rpos_t trigger_rpos = rpos_t::None;
3147 4454258 bool single16 = false;
3148
3149 4454258 std::vector<std::pair<int, int>> coords;
3150
1/2
✓ Branch 0 taken 4454258 times.
✗ Branch 1 not taken.
4454258 coords.push_back({x, y});
3151
1/2
✓ Branch 0 taken 4454258 times.
✗ Branch 1 not taken.
4454258 coords.push_back({x + 15, y});
3152
1/2
✓ Branch 0 taken 4454258 times.
✗ Branch 1 not taken.
4454258 coords.push_back({x, y + 15});
3153
1/2
✓ Branch 0 taken 4454258 times.
✗ Branch 1 not taken.
4454258 coords.push_back({x + 15, y + 15});
3154 4454258 std::vector<rpos_t> rposes_seen;
3155
2/2
✓ Branch 0 taken 4451861 times.
✓ Branch 1 taken 17811750 times.
84483617 for (auto [x, y] : coords)
3156 {
3157
2/4
✓ Branch 0 taken 17811750 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17811750 times.
✗ Branch 3 not taken.
35623500 rpos_t rpos = COMBOPOS_REGION_B(x, y);
3158
2/2
✓ Branch 0 taken 17599367 times.
✓ Branch 1 taken 212383 times.
17811750 if (rpos == rpos_t::None)
3159 212383 continue;
3160
3161
4/6
✓ Branch 0 taken 17599367 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17599367 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 17599356 times.
35198734 if (MAPFFCOMBOFLAG(x, y) == flag)
3162 {
3163
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
22 screen = get_screen_for_world_xy(x, y);
3164 11 break;
3165 }
3166
3167 17599356 bool seen = false;
3168
2/2
✓ Branch 0 taken 13508239 times.
✓ Branch 1 taken 22128287 times.
35636526 for (rpos_t r : rposes_seen)
3169 {
3170
2/2
✓ Branch 0 taken 18037170 times.
✓ Branch 1 taken 4091117 times.
22128287 if (r == rpos)
3171 {
3172 4091117 seen = true;
3173 4091117 break;
3174 }
3175 }
3176
2/2
✓ Branch 0 taken 13508239 times.
✓ Branch 1 taken 4091117 times.
17599356 if (seen)
3177 4091117 continue;
3178
3179
1/2
✓ Branch 0 taken 13508239 times.
✗ Branch 1 not taken.
13508239 rposes_seen.push_back(rpos);
3180
4/6
✓ Branch 0 taken 13508239 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13508239 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2386 times.
✓ Branch 5 taken 13505853 times.
27016478 if (has_flag_trigger(x, y, flag, trigger_rpos, single16))
3181 {
3182
2/4
✓ Branch 0 taken 2386 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2386 times.
✗ Branch 3 not taken.
4772 screen = get_screen_for_world_xy(x, y);
3183 2386 break;
3184 }
3185 }
3186
3187
3/4
✓ Branch 0 taken 2397 times.
✓ Branch 1 taken 4451861 times.
✓ Branch 2 taken 2397 times.
✗ Branch 3 not taken.
4454258 if (screen != -1) scr = get_scr(screen);
3188
2/2
✓ Branch 0 taken 2397 times.
✓ Branch 1 taken 4451861 times.
4454258 if (!scr) return false;
3189
3190
2/2
✓ Branch 0 taken 1958 times.
✓ Branch 1 taken 439 times.
2397 if (trigger_rpos == rpos_t::None)
3191 {
3192 1958 checktrigger = true;
3193
1/2
✓ Branch 0 taken 1958 times.
✗ Branch 1 not taken.
1958 trigger_secrets_for_screen(TriggerSource::Unspecified, screen);
3194 1958 }
3195 else
3196 {
3197 439 checktrigger = true;
3198
2/4
✓ Branch 0 taken 439 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 439 times.
✗ Branch 3 not taken.
439 trigger_secrets_for_screen(TriggerSource::Singular, scr, single16, RPOS_TO_POS(trigger_rpos));
3199 }
3200
3201
1/2
✓ Branch 0 taken 2397 times.
✗ Branch 1 not taken.
2397 sfx(scr->secretsfx);
3202
3203
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2391 times.
2397 if(scr->flags6&fTRIGGERFPERM)
3204 {
3205
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 int32_t flags_remaining = findtrigger(screen); //Normal flags
3206
3207
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (flags_remaining)
3208 {
3209
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 Z_eventlog("Hit All Triggers->Perm Secret not fulfilled (%d trigger flag%s remain).\n", flags_remaining, flags_remaining>1?"s":"");
3210 3 setflag=false;
3211 3 }
3212
3213 // Only actually trigger secrets now if 1) all triggers are gone and 2) QR qr_ALLTRIG_PERMSEC_NO_TEMP is off, in
3214 // which case only the screen state for mSECRET may be set below.
3215
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
6 if (!flags_remaining && !get_qr(qr_ALLTRIG_PERMSEC_NO_TEMP))
3216 {
3217 trigger_secrets_for_screen(TriggerSource::Unspecified, scr, scr->flags6&fTRIGGERF1631, -1);
3218 }
3219 6 }
3220
3221
5/6
✓ Branch 0 taken 2292 times.
✓ Branch 1 taken 105 times.
✓ Branch 2 taken 2292 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1108 times.
✓ Branch 5 taken 1184 times.
2397 if (setflag && canPermSecret(cur_dmap, screen))
3222
2/2
✓ Branch 0 taken 721 times.
✓ Branch 1 taken 463 times.
1905 if(!(scr->flags5&fTEMPSECRETS))
3223
1/2
✓ Branch 0 taken 721 times.
✗ Branch 1 not taken.
721 setmapflag(scr, mSECRET);
3224
3225 2397 return true;
3226 4457867 }
3227
3228 14809016 void update_slopes()
3229 {
3230
2/2
✓ Branch 0 taken 142356 times.
✓ Branch 1 taken 14809016 times.
14951372 for (auto& p : slopes)
3231 {
3232 142356 slope_object& s = p.second;
3233 142356 s.updateslope(); //sets old x/y poses
3234 }
3235 14809016 }
3236
3237 14402367 void update_freeform_combos()
3238 {
3239 14402367 ffscript_engine(false);
3240
2/2
✓ Branch 0 taken 24172 times.
✓ Branch 1 taken 14378195 times.
14402367 if ( !FFCore.system_suspend[susptUPDATEFFC] )
3241 {
3242 14378195 int wrap_right = world_w + 32;
3243 14378195 int wrap_bottom = world_h + 32;
3244
3245 485520729 for_every_ffc([&](const ffc_handle_t& ffc_handle) {
3246 471142534 mapscr* scr = ffc_handle.scr;
3247 471142534 ffcdata& thisffc = *ffc_handle.ffc;
3248
3249 // Combo 0?
3250
2/2
✓ Branch 0 taken 44992239 times.
✓ Branch 1 taken 426150295 times.
471142534 if(thisffc.data==0)
3251 426150295 return;
3252
3253 // Changer?
3254
2/2
✓ Branch 0 taken 543029 times.
✓ Branch 1 taken 44449210 times.
44992239 if(thisffc.flags&ffc_changer)
3255 543029 return;
3256
3257 // Stationary?
3258
2/2
✓ Branch 0 taken 9844 times.
✓ Branch 1 taken 44439366 times.
44449210 if(thisffc.flags&ffc_stationary)
3259 9844 return;
3260
3261 // Frozen because Hero's holding up an item?
3262
3/4
✓ Branch 0 taken 138282 times.
✓ Branch 1 taken 44301084 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 138282 times.
44439366 if(Hero.getHoldClk()>0 && (thisffc.flags&ffc_ignoreholdup)==0)
3263 138282 return;
3264
3265 // Check for changers
3266
2/2
✓ Branch 0 taken 29543786 times.
✓ Branch 1 taken 14757298 times.
44301084 if (thisffc.link==0)
3267 {
3268 442453159 for_some_ffcs([&](const ffc_handle_t& other_ffc_handle) {
3269
2/2
✓ Branch 0 taken 14755762 times.
✓ Branch 1 taken 412940099 times.
427695861 if (ffc_handle.id == other_ffc_handle.id)
3270 14755762 return true;
3271
3272 412940099 ffcdata& otherffc = *other_ffc_handle.ffc;
3273 // Combo 0?
3274
2/2
✓ Branch 0 taken 144689583 times.
✓ Branch 1 taken 268250516 times.
412940099 if(otherffc.data==0)
3275 268250516 return true;
3276
3277 // Not a changer?
3278
2/2
✓ Branch 0 taken 140701406 times.
✓ Branch 1 taken 3988177 times.
144689583 if(!(otherffc.flags&ffc_changer))
3279 140701406 return true;
3280
3281 // Ignore this changer?
3282
4/4
✓ Branch 0 taken 546579 times.
✓ Branch 1 taken 3441598 times.
✓ Branch 2 taken 299257 times.
✓ Branch 3 taken 3142341 times.
3988177 if((otherffc.x.getInt()==thisffc.changer_x&&otherffc.y.getInt()==thisffc.changer_y) || thisffc.flags&ffc_ignorechanger)
3283 845836 return true;
3284
3285
3/4
✓ Branch 0 taken 2721043 times.
✓ Branch 1 taken 421298 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3562 times.
3145903 if((isonline(thisffc.x.getZLong(), thisffc.y.getZLong(), thisffc.prev_changer_x, thisffc.prev_changer_y, otherffc.x.getZLong(), otherffc.y.getZLong()) || // Along the line, or...
3286 ( // At exactly the same position,
3287
2/2
✓ Branch 0 taken 208792 times.
✓ Branch 1 taken 2512251 times.
2721043 (thisffc.x==otherffc.x && thisffc.y==otherffc.y))
3288
2/2
✓ Branch 0 taken 2303459 times.
✓ Branch 1 taken 2512251 times.
208792 ||
3289 //or imprecision and close enough
3290
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
5024502 ( (thisffc.flags&ffc_imprecisionchanger) && ((abs(thisffc.x.getZLong() - otherffc.x.getZLong()) < 10000) && abs(thisffc.y.getZLong() - otherffc.y.getZLong()) < 10000) )
3291 )
3292 && //and...
3293
2/2
✓ Branch 0 taken 3562 times.
✓ Branch 1 taken 2721195 times.
2724757 (thisffc.prev_changer_x>-10000000 && thisffc.prev_changer_y>-10000000)) // This isn't the first frame on this screen
3294 {
3295 3562 zc_ffc_changer(thisffc, otherffc, ffc_handle.id, other_ffc_handle.id);
3296 3562 return false;
3297 }
3298
3299 2721195 return true;
3300 426679763 });
3301 14757298 }
3302
3303
2/2
✓ Branch 0 taken 29543786 times.
✓ Branch 1 taken 14757298 times.
44301084 ffcdata* linked_ffc = thisffc.link ? get_ffc_handle(thisffc.link - 1).ffc : nullptr;
3304
4/4
✓ Branch 0 taken 14757298 times.
✓ Branch 1 taken 29543786 times.
✓ Branch 2 taken 14680008 times.
✓ Branch 3 taken 14863778 times.
44301084 if (linked_ffc ? !linked_ffc->delay : !thisffc.delay)
3305 {
3306
4/4
✓ Branch 0 taken 182609 times.
✓ Branch 1 taken 14681169 times.
✓ Branch 2 taken 85331 times.
✓ Branch 3 taken 97278 times.
14863778 if(thisffc.link && (thisffc.link-1) != ffc_handle.id)
3307 {
3308 97278 thisffc.prev_changer_x = thisffc.x.getZLong();
3309 97278 thisffc.prev_changer_y = thisffc.y.getZLong();
3310 97278 thisffc.x += linked_ffc->vx;
3311 97278 thisffc.y += linked_ffc->vy;
3312 97278 }
3313 else
3314 {
3315 14766500 thisffc.prev_changer_x = thisffc.x.getZLong();
3316 14766500 thisffc.prev_changer_y = thisffc.y.getZLong();
3317 14766500 thisffc.x += thisffc.vx;
3318 14766500 thisffc.y += thisffc.vy;
3319 14766500 thisffc.vx += thisffc.ax;
3320 14766500 thisffc.vy += thisffc.ay;
3321
3322
3323
2/2
✓ Branch 0 taken 444046 times.
✓ Branch 1 taken 14322454 times.
14766500 if(get_qr(qr_OLD_FFC_SPEED_CAP))
3324 {
3325
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vx>128) thisffc.vx=128;
3326
3327
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vx<-128) thisffc.vx=-128;
3328
3329
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vy>128) thisffc.vy=128;
3330
3331
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vy<-128) thisffc.vy=-128;
3332 14322454 }
3333 }
3334 14863778 }
3335 else
3336 {
3337
3/4
✓ Branch 0 taken 1161 times.
✓ Branch 1 taken 76129 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1161 times.
29437306 if(!thisffc.link || (thisffc.link-1) == ffc_handle.id)
3338 76129 thisffc.delay--;
3339 }
3340
3341 // Check if the FFC's off the side of the screen
3342
3343 // Left
3344
2/2
✓ Branch 0 taken 10449 times.
✓ Branch 1 taken 14930619 times.
14941068 if(thisffc.x<-32)
3345 {
3346
2/2
✓ Branch 0 taken 253 times.
✓ Branch 1 taken 10196 times.
10449 if(scr->flags6&fWRAPAROUNDFF)
3347 {
3348 253 thisffc.x = wrap_right+(thisffc.x+32);
3349 253 thisffc.solid_update(false);
3350 253 thisffc.prev_changer_y = thisffc.y.getZLong();
3351 // Re-enable previous changer
3352 253 thisffc.changer_x = -1000;
3353 253 thisffc.changer_y = -1000;
3354 253 }
3355
2/2
✓ Branch 0 taken 10127 times.
✓ Branch 1 taken 69 times.
10196 else if(thisffc.x<-64)
3356 {
3357 69 zc_ffc_set(thisffc, 0);
3358 69 thisffc.flags&=~ffc_carryover;
3359 69 }
3360 10449 }
3361 // Right
3362
2/2
✓ Branch 0 taken 14930438 times.
✓ Branch 1 taken 181 times.
14930619 else if(thisffc.x>=wrap_right)
3363 {
3364
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 53 times.
181 if(scr->flags6&fWRAPAROUNDFF)
3365 {
3366 128 thisffc.x = thisffc.x-wrap_right-32;
3367 128 thisffc.solid_update(false);
3368 128 thisffc.prev_changer_y = thisffc.y.getZLong();
3369 128 thisffc.changer_x = -1000;
3370 128 thisffc.changer_y = -1000;
3371 128 }
3372 else
3373 {
3374 53 zc_ffc_set(thisffc, 0);
3375 53 thisffc.flags&=~ffc_carryover;
3376 }
3377 181 }
3378
3379 // Top
3380
2/2
✓ Branch 0 taken 25480 times.
✓ Branch 1 taken 14915588 times.
14941068 if(thisffc.y<-32)
3381 {
3382
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 25472 times.
25480 if(scr->flags6&fWRAPAROUNDFF)
3383 {
3384 8 thisffc.y = wrap_bottom+(thisffc.y+32);
3385 8 thisffc.solid_update(false);
3386 8 thisffc.prev_changer_x = thisffc.x.getZLong();
3387 8 thisffc.changer_x = -1000;
3388 8 thisffc.changer_y = -1000;
3389 8 }
3390
2/2
✓ Branch 0 taken 25155 times.
✓ Branch 1 taken 317 times.
25472 else if(thisffc.y<-64)
3391 {
3392 317 zc_ffc_set(thisffc, 0);
3393 317 thisffc.flags&=~ffc_carryover;
3394 317 }
3395 25480 }
3396 // Bottom
3397
2/2
✓ Branch 0 taken 14914744 times.
✓ Branch 1 taken 844 times.
14915588 else if(thisffc.y>=wrap_bottom)
3398 {
3399
2/2
✓ Branch 0 taken 753 times.
✓ Branch 1 taken 91 times.
844 if(scr->flags6&fWRAPAROUNDFF)
3400 {
3401 753 thisffc.y = thisffc.y-wrap_bottom-32;
3402 753 thisffc.solid_update(false);
3403 753 thisffc.prev_changer_y = thisffc.x.getZLong();
3404 753 thisffc.changer_x = -1000;
3405 753 thisffc.changer_y = -1000;
3406 753 }
3407 else
3408 {
3409 91 zc_ffc_set(thisffc, 0);
3410 91 thisffc.flags&=~ffc_carryover;
3411 }
3412 844 }
3413 14941068 thisffc.solid_update();
3414 441782518 });
3415 14378195 }
3416 14402367 }
3417
3418 2098420 bool hitcombo(int32_t x, int32_t y, int32_t combotype, byte layers)
3419 {
3420
2/2
✓ Branch 0 taken 14685796 times.
✓ Branch 1 taken 2097896 times.
16783692 for(int q = 0; q < 7; ++q)
3421 {
3422
2/2
✓ Branch 0 taken 12587376 times.
✓ Branch 1 taken 2098420 times.
14685796 if(layers&(1<<q)) //if layer is to be checked
3423
2/2
✓ Branch 0 taken 2097896 times.
✓ Branch 1 taken 524 times.
2098420 if(COMBOTYPE2(q-1,x,y)==combotype) //matching type
3424 524 return true;
3425 14685272 }
3426 2097896 return false;
3427 2098420 }
3428
3429 419684 int gethitcombo(int32_t x, int32_t y, int32_t combotype, byte layers)
3430 {
3431
2/2
✓ Branch 0 taken 2937788 times.
✓ Branch 1 taken 419684 times.
3357472 for(int q = 0; q < 7; ++q)
3432 {
3433
2/2
✓ Branch 0 taken 2518104 times.
✓ Branch 1 taken 419684 times.
2937788 if(layers&(1<<q)) //if layer is to be checked
3434
1/2
✓ Branch 0 taken 419684 times.
✗ Branch 1 not taken.
419684 if(COMBOTYPE2(q-1,x,y)==combotype) //matching type
3435 return MAPCOMBO2(q-1,x,y);
3436 2937788 }
3437 419684 return -1;
3438 419684 }
3439
3440 bool hitflag(int32_t x, int32_t y, int32_t flagtype, byte layers)
3441 {
3442 for(int q = 0; q < 7; ++q)
3443 {
3444 if(layers&(1<<q)) //if layer is to be checked
3445 if(MAPFLAG2(q-1,x,y)==flagtype||MAPCOMBOFLAG2(q-1,x,y)==flagtype) //matching flag
3446 return true;
3447 }
3448 return false;
3449 }
3450
3451 231 optional<int> nextscr(int screen, int dir)
3452 {
3453 231 auto [m, s] = nextscr2(cur_map, screen, dir);
3454
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 231 times.
231 if (m == -1) return nullopt;
3455 462 return (m<<7) + s;
3456 231 }
3457
3458 1058 std::pair<int32_t, int32_t> nextscr2(int32_t dir)
3459 {
3460 1058 int32_t map = cur_map;
3461
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1058 times.
1058 int32_t screen = screenscrolling ? scrolling_hero_screen : hero_screen;
3462 1058 return nextscr2(map, screen, dir);
3463 }
3464
3465 5576 std::pair<int32_t, int32_t> nextscr2(int map, int screen, int32_t dir)
3466 {
3467 5576 screen = screen_index_direction(screen, (direction)dir);
3468
3469 // need to check for screens on other maps, 's' not valid, etc.
3470 5576 int32_t index = (hero_scr->sidewarpindex >> (dir*2))&3;
3471
3472 // Fun fact: when a scrolling warp is triggered, this function
3473 // is never even called! - Saf
3474
2/2
✓ Branch 0 taken 3326 times.
✓ Branch 1 taken 2250 times.
6120 if(hero_scr->sidewarptype[index] == 3) // scrolling warp
3475 {
3476
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 482 times.
✓ Branch 2 taken 525 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 697 times.
2250 switch(dir)
3477 {
3478 case up:
3479
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 399 times.
482 if(!(hero_scr->flags2&wfUP)) goto nowarp;
3480
3481 83 break;
3482
3483 case down:
3484
2/2
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 446 times.
525 if(!(hero_scr->flags2&wfDOWN)) goto nowarp;
3485
3486 79 break;
3487
3488 case left:
3489
2/2
✓ Branch 0 taken 209 times.
✓ Branch 1 taken 337 times.
546 if(!(hero_scr->flags2&wfLEFT)) goto nowarp;
3490
3491 209 break;
3492
3493 case right:
3494
2/2
✓ Branch 0 taken 173 times.
✓ Branch 1 taken 524 times.
697 if(!(hero_scr->flags2&wfRIGHT)) goto nowarp;
3495
3496 173 break;
3497 }
3498
3499 544 map = DMaps[hero_scr->sidewarpdmap[index]].map;
3500 544 screen = hero_scr->sidewarpscr[index] + DMaps[hero_scr->sidewarpdmap[index]].xoff;
3501 544 }
3502
3503 nowarp:
3504
4/4
✓ Branch 0 taken 5512 times.
✓ Branch 1 taken 64 times.
✓ Branch 2 taken 112 times.
✓ Branch 3 taken 5400 times.
5576 if(screen<0||screen>=128)
3505 176 return {-1, -1};
3506
3507 5400 return {map, screen};
3508 5576 }
3509
3510 403 optional<int> nextscr_mi(int mi, int dir)
3511 {
3512 403 int map = mi/MAPSCRSNORMAL;
3513 403 int screen = mi%MAPSCRSNORMAL;
3514 403 auto [m, s] = nextscr2(map, screen, dir);
3515
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 402 times.
403 if (m == -1) return nullopt;
3516 804 return (m<<7) + s;
3517 403 }
3518
3519 2114 void bombdoor(int32_t x,int32_t y)
3520 {
3521
2/2
✓ Branch 0 taken 2094 times.
✓ Branch 1 taken 20 times.
2114 if (!is_in_world_bounds(x, y))
3522 20 return;
3523
3524 2094 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
3525 2094 mapscr* scr = rpos_handle.scr;
3526 2094 int screen = scr->screen;
3527 2902 auto [x0, y0] = translate_screen_coordinates_to_world(rpos_handle.screen);
3528 #define CHECK_RECT(x,y,rx1,ry1,rx2,ry2) (isinRect(x,y,x0+rx1,y0+ry1,x0+rx2,y0+ry2))
3529
3530
12/12
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 2015 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 69 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 69 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 69 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 69 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 69 times.
2094 if(scr->door[0]==dBOMB && CHECK_RECT(x,y,100,0,139,48))
3531 {
3532 69 scr->door[0]=dBOMBED;
3533 69 putdoor(scr, scrollbuf, 0, dBOMBED);
3534 69 setmapflag(scr, mDOOR_UP);
3535 69 markBmap(-1, screen);
3536
3537
1/2
✓ Branch 0 taken 69 times.
✗ Branch 1 not taken.
69 if(auto v = nextscr(screen, up))
3538 {
3539 69 setmapflag_mi(*v, mDOOR_DOWN);
3540 69 markBmap(-1,*v-(get_currdmap()<<7));
3541 69 }
3542 69 }
3543
3544
12/12
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 2045 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 39 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 39 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 39 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 39 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 39 times.
2094 if(scr->door[1]==dBOMB && CHECK_RECT(x,y,100,112,139,176))
3545 {
3546 39 scr->door[1]=dBOMBED;
3547 39 putdoor(scr, scrollbuf, 1, dBOMBED);
3548 39 setmapflag(scr, mDOOR_DOWN);
3549 39 markBmap(-1, rpos_handle.screen);
3550
3551
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 if(auto v = nextscr(rpos_handle.screen, down))
3552 {
3553 39 setmapflag_mi(*v, mDOOR_UP);
3554 39 markBmap(-1,*v-(get_currdmap()<<7));
3555 39 }
3556 39 }
3557
3558
12/12
✓ Branch 0 taken 67 times.
✓ Branch 1 taken 2027 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 51 times.
✓ Branch 4 taken 16 times.
✓ Branch 5 taken 51 times.
✓ Branch 6 taken 16 times.
✓ Branch 7 taken 51 times.
✓ Branch 8 taken 16 times.
✓ Branch 9 taken 51 times.
✓ Branch 10 taken 16 times.
✓ Branch 11 taken 51 times.
2094 if(scr->door[2]==dBOMB && CHECK_RECT(x,y,0,60,48,98))
3559 {
3560 51 scr->door[2]=dBOMBED;
3561 51 putdoor(scr, scrollbuf, 2, dBOMBED);
3562 51 setmapflag(scr, mDOOR_LEFT);
3563 51 markBmap(-1, rpos_handle.screen);
3564
3565
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 if(auto v = nextscr(rpos_handle.screen, left))
3566 {
3567 51 setmapflag_mi(*v, mDOOR_RIGHT);
3568 51 markBmap(-1,*v-(get_currdmap()<<7));
3569 51 }
3570 51 }
3571
3572
12/12
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 2008 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 72 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 72 times.
✓ Branch 6 taken 14 times.
✓ Branch 7 taken 72 times.
✓ Branch 8 taken 14 times.
✓ Branch 9 taken 72 times.
✓ Branch 10 taken 14 times.
✓ Branch 11 taken 72 times.
2094 if(scr->door[3]==dBOMB && CHECK_RECT(x,y,192,60,240,98))
3573 {
3574 72 scr->door[3]=dBOMBED;
3575 72 putdoor(scr, scrollbuf, 3, dBOMBED);
3576 72 setmapflag(scr, mDOOR_RIGHT);
3577 72 markBmap(-1, rpos_handle.screen);
3578
3579
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 if(auto v = nextscr(rpos_handle.screen, right))
3580 {
3581 72 setmapflag_mi(*v, mDOOR_LEFT);
3582 72 markBmap(-1,*v-(get_currdmap()<<7));
3583 72 }
3584 72 }
3585 2114 }
3586
3587 6384285067 void draw_cmb(BITMAP* dest, int32_t x, int32_t y, int32_t cid, int32_t cset,
3588 bool over, bool transp)
3589 {
3590 6384285067 auto& cmb = combobuf[cid];
3591
2/2
✓ Branch 0 taken 90743 times.
✓ Branch 1 taken 6384194324 times.
6384285067 if(cmb.animflags & AF_EDITOR_ONLY)
3592 90743 return;
3593
2/2
✓ Branch 0 taken 3309355746 times.
✓ Branch 1 taken 3074838578 times.
6384194324 if(over)
3594 {
3595
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3309355746 times.
3309355746 if(cmb.animflags & AF_TRANSPARENT)
3596 transp = !transp;
3597
2/2
✓ Branch 0 taken 319148412 times.
✓ Branch 1 taken 2990207334 times.
3309355746 if(transp)
3598 319148412 overcombotranslucent(dest, x, y, cid, cset, 128);
3599 2990207334 else overcombo(dest, x, y, cid, cset);
3600 3309355746 }
3601 3074838578 else putcombo(dest, x, y, cid, cset);
3602 6384285067 }
3603 6384293515 void draw_cmb_pos(BITMAP* dest, int32_t x, int32_t y, rpos_t rpos, int32_t cid,
3604 int32_t cset, byte layer, bool over, bool transp)
3605 {
3606
2/2
✓ Branch 0 taken 750736355 times.
✓ Branch 1 taken 5633557160 times.
6384293515 if (rpos != rpos_t::None)
3607 {
3608 5633557160 rpos_t plrpos = COMBOPOS_REGION_B(Hero.x+8, Hero.y+8);
3609
2/2
✓ Branch 0 taken 749524 times.
✓ Branch 1 taken 5632807636 times.
5633557160 if (plrpos != rpos_t::None)
3610 {
3611 5632807636 bool dosw = false;
3612
4/4
✓ Branch 0 taken 52860 times.
✓ Branch 1 taken 5632754776 times.
✓ Branch 2 taken 44412 times.
✓ Branch 3 taken 8448 times.
5632807636 if (rpos == hooked_comborpos && (hooked_layerbits & (1<<layer)))
3613 {
3614
1/2
✓ Branch 0 taken 8448 times.
✗ Branch 1 not taken.
8448 if(hooked_undercombos[layer] > -1)
3615 {
3616 draw_cmb(dest, x, y,
3617 hooked_undercombos[layer], hooked_undercombos[layer+7], over, transp);
3618 }
3619 8448 dosw = true;
3620 8448 }
3621
4/4
✓ Branch 0 taken 31973655 times.
✓ Branch 1 taken 5600825533 times.
✓ Branch 2 taken 8448 times.
✓ Branch 3 taken 31965207 times.
5632799188 else if (rpos == plrpos && (hooked_layerbits & (1<<(layer+8))))
3622 {
3623 8448 dosw = true;
3624 8448 }
3625
2/2
✓ Branch 0 taken 5632790740 times.
✓ Branch 1 taken 16896 times.
5632807636 if (dosw)
3626 {
3627
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 16896 times.
✗ Branch 3 not taken.
16896 switch (Hero.switchhookstyle)
3628 {
3629 default: case swPOOF:
3630 break; //Nothing special here
3631 case swFLICKER:
3632 {
3633
2/2
✓ Branch 0 taken 8448 times.
✓ Branch 1 taken 8448 times.
16896 if(abs(Hero.switchhookclk-33)&0b1000)
3634 8448 break; //Drawn this frame
3635 8448 return; //Not drawn this frame
3636 }
3637 case swRISE:
3638 {
3639 //Draw rising up
3640 y -= 8-(abs(Hero.switchhookclk-32)/4);
3641 break;
3642 }
3643 }
3644 8448 }
3645 5632799188 }
3646 5633548712 }
3647
3648 6384285067 draw_cmb(dest, x, y, cid, cset, over, transp);
3649 6384293515 }
3650
3651 // `draw_cmb_pos` only does meaningful work if the combo being drawn is within the bounds of
3652 // the `bmp` bitmap. However, even getting to the point where `puttile16` (for example) knows
3653 // to cull is somewhat expensive. Since it can only draw 16x16 pixels, we can do the equivalent
3654 // culling here by determining the rows/columns that are within the bitmap bounds. This nets
3655 // on the order of ~30 FPS in uncapped mode on my machine, depending on the viewport/region size.
3656 //
3657 // These two inequalities must be true for `draw_cmb_pos` to do anything useful:
3658 //
3659 // -16 < comboPositionX*16 + x < bitmapWidth
3660 // -16 < comboPositionY*16 + y < bitmapHeight
3661 //
3662 // The following start/end values are derived directly from the above.
3663 //
3664 // `x` and `y` are the offsets the combos will be drawn into the bitmap.
3665 39481684 static void get_bounds_for_draw_cmb_calls(BITMAP* bmp, int x, int y, int& start_x, int& end_x, int& start_y, int& end_y)
3666 {
3667 // if (bmp->clip)
3668 // {
3669 // start_x = MAX(0, ceil((bmp->cl - 15 - x) / 16.0));
3670 // end_x = MIN(16, ceil((bmp->cr - x) / 16.0));
3671 // start_y = MAX(0, ceil((bmp->ct - 15 - y) / 16.0));
3672 // end_y = MIN(11, ceil((bmp->cb - y) / 16.0));
3673 // return;
3674 // }
3675
3676
2/2
✓ Branch 0 taken 2169310 times.
✓ Branch 1 taken 37312374 times.
39481684 start_x = MAX(0, ceil((-15 - x) / 16.0));
3677
2/2
✓ Branch 0 taken 2178501 times.
✓ Branch 1 taken 37303183 times.
39481684 end_x = MIN(16, ceil((bmp->w - x) / 16.0));
3678
2/2
✓ Branch 0 taken 38092426 times.
✓ Branch 1 taken 1389258 times.
39481684 start_y = MAX(0, ceil((-15 - y) / 16.0));
3679
2/2
✓ Branch 0 taken 1678576 times.
✓ Branch 1 taken 37803108 times.
39481684 end_y = MIN(11, ceil((bmp->h - y) / 16.0));
3680 39481684 }
3681
3682 186959122 void do_ffc_layer(BITMAP* bmp, int32_t layer, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3683 {
3684
1/2
✓ Branch 0 taken 186959122 times.
✗ Branch 1 not taken.
186959122 if(!show_ffcs) return;
3685 186959122 mapscr* scr = screen_handle.scr;
3686 186959122 mapscr* base_scr = screen_handle.base_scr;
3687
3688 186959122 y += playing_field_offset;
3689
3690 186959122 bool is_bg_layer = layer < -1;
3691
2/2
✓ Branch 0 taken 33926319 times.
✓ Branch 1 taken 153032803 times.
186959122 int real_layer = is_bg_layer ? abs(layer) : layer;
3692
2/2
✓ Branch 0 taken 186959122 times.
✓ Branch 1 taken 5581191896 times.
5768151018 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3693 {
3694
2/2
✓ Branch 0 taken 5375694200 times.
✓ Branch 1 taken 205497696 times.
5581191896 if (base_scr->ffcs[i].data == 0)
3695 5375694200 continue;
3696
4/4
✓ Branch 0 taken 37360962 times.
✓ Branch 1 taken 168136734 times.
✓ Branch 2 taken 18682962 times.
✓ Branch 3 taken 18678000 times.
205497696 if(real_layer == 2 && (is_bg_layer != XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG)))
3697 18678000 continue;
3698
4/4
✓ Branch 0 taken 37360962 times.
✓ Branch 1 taken 149458734 times.
✓ Branch 2 taken 18682962 times.
✓ Branch 3 taken 18678000 times.
186819696 else if (real_layer == 3 && (is_bg_layer != XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)))
3699 18678000 continue;
3700
4/4
✓ Branch 0 taken 149463696 times.
✓ Branch 1 taken 18678000 times.
✓ Branch 2 taken 18682962 times.
✓ Branch 3 taken 130780734 times.
168141696 if (real_layer > -1 && base_scr->ffcs[i].layer != real_layer)
3701 130780734 continue;
3702
3703
6/6
✓ Branch 0 taken 3008970 times.
✓ Branch 1 taken 34351992 times.
✓ Branch 2 taken 5110 times.
✓ Branch 3 taken 3003860 times.
✓ Branch 4 taken 2626 times.
✓ Branch 5 taken 2484 times.
37360962 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3704 2484 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3705
3706 37358478 base_scr->ffcs[i].draw_ffc(bmp, x, y, (layer==-1));
3707 37358478 }
3708 186959122 }
3709 170936018 void _do_current_ffc_layer(BITMAP* bmp, int32_t layer)
3710 {
3711
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 170936018 times.
170936018 if(!show_ffcs) return;
3712 346450258 for_every_base_screen_in_region([&](mapscr* base_scr, unsigned int region_scr_x, unsigned int region_scr_y) {
3713 175514240 screen_handle_t handle = {base_scr, base_scr, base_scr->screen, 0};
3714 175514240 do_ffc_layer(bmp, layer, handle, 0, 0);
3715 175514240 });
3716 170936018 }
3717 75616363 void do_scrolling_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3718 {
3719 75616363 mapscr* scr = screen_handle.scr;
3720 75616363 mapscr* base_scr = screen_handle.base_scr;
3721
3722
4/4
✓ Branch 0 taken 60951253 times.
✓ Branch 1 taken 14665110 times.
✓ Branch 2 taken 14665110 times.
✓ Branch 3 taken 75616363 times.
75616363 if (type == -3 || type == -4)
3723 {
3724 29330220 y += playing_field_offset;
3725
3726
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
29330220 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3727 {
3728 if (base_scr->ffcs[i].data == 0)
3729 continue;
3730
3731 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3732 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3733
3734 base_scr->ffcs[i].draw_ffc(bmp, x, y, (type==-4));
3735 }
3736 return;
3737 }
3738
3739 75616363 x -= viewport.x;
3740 75616363 y -= viewport.y - playing_field_offset;
3741
3742 75616363 bool over = true, transp = false;
3743 75616363 int layer = screen_handle.layer;
3744
3745
7/8
✓ Branch 0 taken 55150603 times.
✓ Branch 1 taken 20465760 times.
✓ Branch 2 taken 13148698 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 34184937 times.
✓ Branch 5 taken 20965666 times.
✓ Branch 6 taken 3060006 times.
✓ Branch 7 taken 4257056 times.
75616363 switch(type ? type : layer)
3746 {
3747 case -2: //push blocks
3748
2/2
✓ Branch 0 taken 19519827 times.
✓ Branch 1 taken 14665110 times.
34184937 if (scr)
3749 {
3750
2/2
✓ Branch 0 taken 3435489552 times.
✓ Branch 1 taken 23710689 times.
3434983425 for(int32_t i=0; i<176; i++)
3751 {
3752 3435489552 int32_t mf=scr->sflag[i], mf2 = combobuf[scr->data[i]].flag;
3753
3754
10/10
✓ Branch 0 taken 3435319208 times.
✓ Branch 1 taken 170344 times.
✓ Branch 2 taken 3433847236 times.
✓ Branch 3 taken 1471972 times.
✓ Branch 4 taken 3433218253 times.
✓ Branch 5 taken 628983 times.
✓ Branch 6 taken 24420876 times.
✓ Branch 7 taken 3408797377 times.
✓ Branch 8 taken 42763031 times.
✓ Branch 9 taken 16705853 times.
3472537020 if(mf==mfPUSHUD || mf==mfPUSH4 || mf==mfPUSHED || ((mf>=mfPUSHLR)&&(mf<=mfPUSHRINS))
3755
6/8
✓ Branch 0 taken 3430336723 times.
✓ Branch 1 taken 21539346 times.
✓ Branch 2 taken 3430336723 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3430336723 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 37047468 times.
✓ Branch 7 taken 3393289255 times.
3433218253 || mf2==mfPUSHUD || mf2==mfPUSH4 || mf2==mfPUSHED || ((mf2>=mfPUSHLR)&&(mf2<=mfPUSHRINS)))
3756 {
3757
4/4
✓ Branch 0 taken 4772508 times.
✓ Branch 1 taken 695982 times.
✓ Branch 2 taken 3657 times.
✓ Branch 3 taken 4768851 times.
90994552 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3758 5468490 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3759 5468490 }
3760 3415463598 }
3761 23710689 }
3762 38375799 return;
3763
3764 case -1: //over combo
3765
1/2
✓ Branch 0 taken 20965666 times.
✗ Branch 1 not taken.
20965666 if (scr)
3766 {
3767
2/2
✓ Branch 0 taken 3689957216 times.
✓ Branch 1 taken 20965666 times.
3710922882 for(int32_t i=0; i<176; i++)
3768 {
3769
2/2
✓ Branch 0 taken 3670681160 times.
✓ Branch 1 taken 19276056 times.
3689957216 if(combo_class_buf[combobuf[scr->data[i]].type].overhead)
3770 {
3771
4/4
✓ Branch 0 taken 15523213 times.
✓ Branch 1 taken 3752843 times.
✓ Branch 2 taken 22320 times.
✓ Branch 3 taken 15500893 times.
19276056 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3772 19276056 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3773 19276056 }
3774 3689957216 }
3775 20965666 }
3776 20965666 return;
3777
3778 case 1:
3779 case 4:
3780 case 5:
3781 case 6:
3782
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 13148698 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
13148698 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3783 {
3784
1/2
✓ Branch 0 taken 13148698 times.
✗ Branch 1 not taken.
13148698 if (scr)
3785 {
3786
2/2
✓ Branch 0 taken 11489487 times.
✓ Branch 1 taken 1659211 times.
13148698 if(base_scr->layeropacity[layer-1]!=255)
3787 1659211 transp = true;
3788 13148698 break;
3789 }
3790 }
3791 return;
3792
3793 case 2:
3794
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3060006 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3060006 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3795 {
3796
1/2
✓ Branch 0 taken 3060006 times.
✗ Branch 1 not taken.
3060006 if (scr)
3797 {
3798
2/2
✓ Branch 0 taken 2840409 times.
✓ Branch 1 taken 219597 times.
3060006 if(base_scr->layeropacity[layer-1]!=255)
3799 219597 transp = true;
3800
3801
2/2
✓ Branch 0 taken 2931096 times.
✓ Branch 1 taken 128910 times.
3060006 if(XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3802 128910 over = false;
3803
3804 3060006 break;
3805 }
3806 }
3807 return;
3808
3809 case 3:
3810
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4257056 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4257056 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3811 {
3812
1/2
✓ Branch 0 taken 4257056 times.
✗ Branch 1 not taken.
4257056 if (scr)
3813 {
3814
2/2
✓ Branch 0 taken 4183343 times.
✓ Branch 1 taken 73713 times.
4257056 if(base_scr->layeropacity[layer-1]!=255)
3815 73713 transp = true;
3816
3817
2/2
✓ Branch 0 taken 36655 times.
✓ Branch 1 taken 60483 times.
4257056 if(XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)
3818
2/2
✓ Branch 0 taken 97138 times.
✓ Branch 1 taken 4159918 times.
4257056 && !XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3819 60483 over = false;
3820
3821 4257056 break;
3822 }
3823 }
3824 return;
3825 }
3826
3827 int start_x, end_x, start_y, end_y;
3828 20465760 get_bounds_for_draw_cmb_calls(bmp, x, y, start_x, end_x, start_y, end_y);
3829
2/2
✓ Branch 0 taken 20465760 times.
✓ Branch 1 taken 216989886 times.
237455646 for (int cy = start_y; cy < end_y; cy++)
3830 {
3831
2/2
✓ Branch 0 taken 3283736359 times.
✓ Branch 1 taken 216989886 times.
3500726245 for (int cx = start_x; cx < end_x; cx++)
3832 {
3833 3283736359 int i = cx + cy*16;
3834
4/4
✓ Branch 0 taken 2905553132 times.
✓ Branch 1 taken 378183227 times.
✓ Branch 2 taken 10227360 times.
✓ Branch 3 taken 2895325772 times.
3283736359 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3835 3283736359 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, over, transp);
3836 3283736359 }
3837 216989886 }
3838 60951253 }
3839
3840 269000298 bool lenscheck(mapscr* scr, int layer)
3841 {
3842
4/4
✓ Branch 0 taken 268821350 times.
✓ Branch 1 taken 178948 times.
✓ Branch 2 taken 178948 times.
✓ Branch 3 taken 269000298 times.
269000298 if(layer < 0 || layer > 6) return true;
3843
2/2
✓ Branch 0 taken 259586721 times.
✓ Branch 1 taken 9413577 times.
269000298 if(get_qr(qr_OLD_LENS_LAYEREFFECT))
3844 {
3845
2/2
✓ Branch 0 taken 209708941 times.
✓ Branch 1 taken 49877780 times.
259586721 if(!layer) return true;
3846
8/8
✓ Branch 0 taken 34922117 times.
✓ Branch 1 taken 174786824 times.
✓ Branch 2 taken 258970 times.
✓ Branch 3 taken 34663147 times.
✓ Branch 4 taken 143758 times.
✓ Branch 5 taken 163336 times.
✓ Branch 6 taken 326536 times.
✓ Branch 7 taken 34480369 times.
209708941 if((layer==(int32_t)(scr->lens_layer&7)+1) && ((scr->lens_layer&llLENSSHOWS && !lensclk) || (scr->lens_layer&llLENSHIDES && lensclk)))
3847 489872 return false;
3848 209267193 }
3849 else
3850 {
3851
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 9413577 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9413577 times.
9413577 if((lensclk ? scr->lens_hide : scr->lens_show) & (1<<layer))
3852 return false;
3853 }
3854 218680770 return true;
3855 268821350 }
3856
3857 156156659 void do_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3858 {
3859 156156659 bool showlayer = true;
3860 156156659 mapscr* base_scr = screen_handle.base_scr;
3861 156156659 int layer = screen_handle.layer;
3862
2/2
✓ Branch 0 taken 42083663 times.
✓ Branch 1 taken 114072996 times.
156156659 int target = type ? type : layer;
3863
3/4
✓ Branch 0 taken 114072996 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20230595 times.
✓ Branch 3 taken 21853068 times.
156156659 switch(target)
3864 {
3865 case -2:
3866
1/2
✓ Branch 0 taken 20230595 times.
✗ Branch 1 not taken.
20230595 if(!show_layer_push)
3867 showlayer = false;
3868 20230595 break;
3869
3870 case -1:
3871
1/2
✓ Branch 0 taken 21853068 times.
✗ Branch 1 not taken.
21853068 if(!show_layer_over)
3872 showlayer = false;
3873 21853068 break;
3874
3875 case 1: case 2: case 3:
3876 case 4: case 5: case 6:
3877 114072996 showlayer = show_layers[target];
3878 114072996 break;
3879 }
3880
3881
2/2
✓ Branch 0 taken 42083663 times.
✓ Branch 1 taken 114072996 times.
156156659 if(!type)
3882 {
3883
2/2
✓ Branch 0 taken 113936798 times.
✓ Branch 1 taken 136198 times.
114072996 if(!lenscheck(base_scr,layer))
3884 136198 showlayer = false;
3885 114072996 }
3886
3887
2/2
✓ Branch 0 taken 136198 times.
✓ Branch 1 taken 156020461 times.
156156659 if(showlayer)
3888 {
3889
6/6
✓ Branch 0 taken 61007376 times.
✓ Branch 1 taken 95013085 times.
✓ Branch 2 taken 20521883 times.
✓ Branch 3 taken 40485493 times.
✓ Branch 4 taken 56123 times.
✓ Branch 5 taken 20465760 times.
156020461 if (screen_handle.scr && (type || !(base_scr->hidelayers & (1 << (layer)))))
3890 {
3891 60951253 do_scrolling_layer(bmp, type, screen_handle, x, y);
3892
4/4
✓ Branch 0 taken 20465760 times.
✓ Branch 1 taken 40485493 times.
✓ Branch 2 taken 19233766 times.
✓ Branch 3 taken 1231994 times.
60951253 if(!type && !get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
3893
2/2
✓ Branch 0 taken 1231418 times.
✓ Branch 1 taken 576 times.
1232570 if(mblock2.draw(bmp,layer))
3894 576 do_primitives(bmp, SPLAYER_MOVINGBLOCK);
3895 60951253 }
3896 156020461 }
3897 156156659 }
3898
3899 103024659 void do_layer_primitives(BITMAP *bmp, int32_t layer)
3900 {
3901 103024659 bool showlayer = true;
3902
3903
2/4
✓ Branch 0 taken 103024659 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 103024659 times.
103024659 if(layer >= 0 && layer <= 6)
3904 {
3905 103024659 showlayer = show_layers[layer];
3906
3907
2/2
✓ Branch 0 taken 102898057 times.
✓ Branch 1 taken 126602 times.
103024659 if(!lenscheck(origin_scr,layer))
3908 126602 showlayer = false;
3909 103024659 }
3910
3911
2/2
✓ Branch 0 taken 126602 times.
✓ Branch 1 taken 102898057 times.
103024659 if (showlayer)
3912 102898057 do_primitives(bmp, layer);
3913 103024659 }
3914
3915 // Called by do_walkflags
3916 void put_walkflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
3917 {
3918 newcombo const &c = combobuf[cmbdat];
3919
3920 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
3921
3922 int32_t xx = x-xofs;
3923 int32_t yy = y+playing_field_offset-yofs;
3924
3925 int32_t bridgedetected = 0;
3926
3927 for(int32_t i=0; i<4; i++)
3928 {
3929 int32_t tx=((i&2)<<2)+xx - viewport.x;
3930 int32_t ty=((i&1)<<3)+yy - viewport.y;
3931 int32_t tx2=((i&2)<<2)+x - viewport.x;
3932 int32_t ty2=((i&1)<<3)+y - viewport.y;
3933 for (int32_t j = lyr-1; j <= 1; j++)
3934 {
3935 if (get_qr(qr_OLD_BRIDGE_COMBOS))
3936 {
3937 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && !_walkflag_layer(tx2,ty2,j))
3938 {
3939 bridgedetected |= (1<<i);
3940 }
3941 }
3942 else
3943 {
3944 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && _effectflag_layer(tx2,ty2,j))
3945 {
3946 bridgedetected |= (1<<i);
3947 }
3948 }
3949 }
3950 if ((bridgedetected & (1<<i)))
3951 {
3952 if (i >= 3) break;
3953 else continue;
3954 }
3955 bool doladdercheck = true;
3956
3957 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
3958 {
3959 for(int32_t k=0; k<8; k+=2)
3960 for(int32_t j=0; j<8; j+=2)
3961 if(((k+j)/2)%2)
3962 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,makecol(85,85,255));
3963 }
3964 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
3965 {
3966 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
3967 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
3968 rectfill(dest,tx,ty,tx+7,ty+7,makecol(85,85,255));
3969 else rectfill(dest,tx,ty,tx+7,ty+7,makecol(170,170,170));
3970 }
3971
3972 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
3973 {
3974 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
3975 {
3976 for(int32_t k=0; k<8; k+=2)
3977 for(int32_t j=0; j<8; j+=2)
3978 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,((k+j)/2)%2 ? makecol(165,105,8) : makecol(170,170,170));
3979 }
3980 else
3981 {
3982 int32_t color = makecol(178,36,36);
3983
3984 if(isstepable(cmbdat)&& (!doladdercheck))
3985 color=makecol(165,105,8);
3986 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
3987 color=makecol(170,170,170);
3988
3989 rectfill(dest,tx,ty,tx+7,ty+7,color);
3990 }
3991 }
3992 }
3993
3994 // Draw damage combos
3995 bool dmg = combo_class_buf[combobuf[MAPCOMBO2(-1,xx,yy)].type].modify_hp_amount
3996 || combo_class_buf[combobuf[MAPCOMBO2(0,xx,yy)].type].modify_hp_amount
3997 || combo_class_buf[combobuf[MAPCOMBO2(1,xx,yy)].type].modify_hp_amount;
3998
3999 if(dmg)
4000 {
4001 int32_t color = makecol(255,255,0);
4002 if (bridgedetected <= 0)
4003 {
4004 for(int32_t k=0; k<16; k+=2)
4005 for(int32_t j=0; j<16; j+=2)
4006 if(((k+j)/2)%2)
4007 {
4008 int32_t x0 = x - viewport.x;
4009 int32_t y0 = y - viewport.y;
4010 rectfill(dest,x0+k,y0+j,x0+k+1,y0+j+1,color);
4011 }
4012 }
4013 else
4014 {
4015 for(int32_t i=0; i<4; i++)
4016 {
4017 if (!(bridgedetected & (1<<i)))
4018 {
4019 int32_t tx=((i&2)<<2)+x - viewport.x;
4020 int32_t ty=((i&1)<<3)+y - viewport.y;
4021 for(int32_t k=0; k<8; k+=2)
4022 for(int32_t j=0; j<8; j+=2)
4023 if((k+j)%4 < 2) rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,color);
4024 }
4025 }
4026 }
4027 }
4028 }
4029 static void put_walkflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4030 {
4031 ALLEGRO_COLOR col_solid = al_map_rgba(178,36,36,info_opacity);
4032 ALLEGRO_COLOR col_water1 = al_map_rgba(85,85,255,info_opacity);
4033 ALLEGRO_COLOR col_lhook = al_map_rgba(170,170,170,info_opacity);
4034 ALLEGRO_COLOR col_stepable = al_map_rgba(165,105,8,info_opacity);
4035 ALLEGRO_COLOR col_dmg = al_map_rgba(255,255,0,info_opacity);
4036 newcombo const &c = combobuf[cmbdat];
4037
4038 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
4039
4040 int32_t xx = x-viewport.x;
4041 int32_t yy = y+playing_field_offset-viewport.y;
4042
4043 int32_t bridgedetected = 0;
4044
4045 // Draw damage combos
4046 bool dmg = combo_class_buf[c.type].modify_hp_amount;
4047
4048 for(int32_t i=0; i<4; i++)
4049 {
4050 int32_t tx=((i&2)<<2)+xx;
4051 int32_t ty=((i&1)<<3)+yy;
4052 int32_t tx2=((i&2)<<2)+x;
4053 int32_t ty2=((i&1)<<3)+y;
4054 for (int32_t m = lyr-1; m <= 1; m++)
4055 {
4056 if (get_qr(qr_OLD_BRIDGE_COMBOS))
4057 {
4058 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && !_walkflag_layer(tx2, ty2, m))
4059 {
4060 bridgedetected |= (1<<i);
4061 }
4062 }
4063 else
4064 {
4065 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && _effectflag_layer(tx2, ty2, m))
4066 {
4067 bridgedetected |= (1<<i);
4068 }
4069 }
4070 }
4071 if ((bridgedetected & (1<<i)))
4072 continue;
4073 bool doladdercheck = true;
4074
4075 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
4076 {
4077 for(int32_t k=0; k<8; k+=2)
4078 for(int32_t j=0; j<8; j+=2)
4079 if(((k+j)/2)%2)
4080 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_water1);
4081 }
4082 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
4083 {
4084 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
4085 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
4086 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_water1);
4087 else al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_lhook);
4088 }
4089
4090 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
4091 {
4092 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
4093 {
4094 for(int32_t k=0; k<8; k+=2)
4095 for(int32_t j=0; j<8; j+=2)
4096 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,((k+j)/2)%2 ? col_stepable : col_lhook);
4097 }
4098 else
4099 {
4100 ALLEGRO_COLOR* color = &col_solid;
4101
4102 if(isstepable(cmbdat)&& (!doladdercheck))
4103 color=&col_stepable;
4104 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4105 color=&col_lhook;
4106
4107 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,*color);
4108 }
4109 }
4110
4111 if(dmg)
4112 {
4113 for(int32_t k=0; k<8; k+=2)
4114 for(int32_t j=0; j<8; j+=2)
4115 if((k+j)%4 < 2) al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_dmg);
4116 }
4117 }
4118 }
4119
4120 void put_effectflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
4121 {
4122 newcombo const &c = combobuf[cmbdat];
4123
4124 int32_t xx = x-xofs-viewport.x;
4125 int32_t yy = y+playing_field_offset-yofs-viewport.y;
4126
4127 for(int32_t i=0; i<4; i++)
4128 {
4129 int32_t tx=((i&2)<<2)+xx;
4130 int32_t ty=((i&1)<<3)+yy;
4131
4132 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4133 {
4134 int32_t color = vc(10);
4135
4136 rectfill(dest,tx,ty,tx+7,ty+7,color);
4137 }
4138 }
4139 }
4140 static void put_effectflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4141 {
4142 ALLEGRO_COLOR col_eff = al_map_rgba(85,255,85,info_opacity);
4143 newcombo const &c = combobuf[cmbdat];
4144
4145 int32_t xx = x-viewport.x;
4146 int32_t yy = y+playing_field_offset-viewport.y;
4147
4148 for(int32_t i=0; i<4; i++)
4149 {
4150 int32_t tx=((i&2)<<2)+xx;
4151 int32_t ty=((i&1)<<3)+yy;
4152
4153 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4154 {
4155 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_eff);
4156 }
4157 }
4158 }
4159
4160 void draw_ladder_platform(BITMAP* dest, int32_t x, int32_t y, int32_t c)
4161 {
4162 for(auto cx = 0; cx < 256; cx += 16)
4163 {
4164 for(auto cy = 0; cy < 176; cy += 16)
4165 {
4166 if(isSVLadder(cx,cy))
4167 {
4168 auto nx = cx+x, ny = cy+y;
4169 if(cy && !isSVLadder(cx,cy-16))
4170 line(dest,nx,ny,nx+15,ny,c);
4171 rectfill(dest,nx,ny,nx+3,ny+15,c);
4172 rectfill(dest,nx+12,ny,nx+15,ny+15,c);
4173 rectfill(dest,nx+4,ny+2,nx+11,ny+5,c);
4174 rectfill(dest,nx+4,ny+10,nx+11,ny+13,c);
4175 }
4176 else if(isSVPlatform(cx,cy))
4177 {
4178 line(dest,cx+x,cy+y,cx+x+15,cy+y,c);
4179 }
4180 }
4181 }
4182 }
4183 void draw_ladder_platform_a5(int32_t x, int32_t y, ALLEGRO_COLOR c)
4184 {
4185 for(auto cx = 0; cx < 256; cx += 16)
4186 {
4187 for(auto cy = 0; cy < 176; cy += 16)
4188 {
4189 if(isSVLadder(cx,cy))
4190 {
4191 auto nx = cx+x, ny = cy+y;
4192 if(cy && !isSVLadder(cx,cy-16))
4193 al_draw_line(nx,ny,nx+15,ny,c,1);
4194 al_draw_filled_rectangle(nx,ny,nx+4,ny+16,c);
4195 al_draw_filled_rectangle(nx+12,ny,nx+16,ny+16,c);
4196 al_draw_filled_rectangle(nx+4,ny+2,nx+12,ny+6,c);
4197 al_draw_filled_rectangle(nx+4,ny+10,nx+12,ny+14,c);
4198 }
4199 else if(isSVPlatform(cx,cy))
4200 {
4201 al_draw_line(cx+x,cy+y,cx+x+15,cy+y,c,1);
4202 }
4203 }
4204 }
4205 }
4206
4207 // Walkflags L4 cheat
4208 void do_walkflags(const screen_handles_t& screen_handles, int32_t x, int32_t y)
4209 {
4210 if (!show_walkflags)
4211 return;
4212
4213 start_info_bmp();
4214
4215 mapscr* scr = screen_handles[0].scr;
4216 for(int32_t i=0; i<176; i++)
4217 {
4218 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4219 }
4220
4221 for(int32_t k=0; k<2; k++)
4222 {
4223 scr = screen_handles[k + 1].scr;
4224
4225 if (scr)
4226 {
4227 for(int32_t i=0; i<176; i++)
4228 {
4229 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], k%2+1);
4230 }
4231 }
4232 }
4233
4234 end_info_bmp();
4235 }
4236
4237 void do_walkflags(int32_t x, int32_t y)
4238 {
4239 if (!show_walkflags)
4240 return;
4241
4242 x += -viewport.x;
4243 y += playing_field_offset - viewport.y;
4244
4245 start_info_bmp();
4246
4247 draw_ladder_platform_a5(x,y,al_map_rgba(165,105,8,info_opacity));
4248 draw_solid_objects_a5(x,y,al_map_rgba(178,36,36,info_opacity));
4249 draw_slopes_a5(x,y,al_map_rgba(255,85,255,info_opacity));
4250
4251 end_info_bmp();
4252 }
4253
4254 // Effectflags L4 cheat
4255 void do_effectflags(mapscr* scr, int32_t x, int32_t y)
4256 {
4257 if(show_effectflags)
4258 {
4259 start_info_bmp();
4260
4261 for(int32_t i=0; i<176; i++)
4262 {
4263 put_effectflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4264 }
4265
4266 end_info_bmp();
4267 }
4268 }
4269
4270 272141 void calc_darkroom_combos(mapscr* scr, int offx, int offy)
4271 {
4272 272141 int map = scr->map;
4273 272141 int screen = scr->screen;
4274
4275
2/2
✓ Branch 0 taken 1904987 times.
✓ Branch 1 taken 272141 times.
2177128 for(int32_t lyr = 0; lyr < 7; ++lyr)
4276 {
4277 1904987 mapscr* scr = get_scr_layer(map, screen, lyr);
4278
2/2
✓ Branch 0 taken 780869 times.
✓ Branch 1 taken 1124118 times.
1904987 if (!scr->is_valid()) continue;
4279
4280
2/2
✓ Branch 0 taken 137432944 times.
✓ Branch 1 taken 780869 times.
138213813 for(int32_t q = 0; q < 176; ++q)
4281 {
4282 137432944 newcombo const& cmb = combobuf[scr->data[q]];
4283
2/2
✓ Branch 0 taken 136828325 times.
✓ Branch 1 taken 604619 times.
137432944 if(cmb.type == cTORCH)
4284 {
4285 604619 do_torch_combo(cmb, COMBOX(q)+8+offx, COMBOY(q)+8+offy, darkscr_bmp);
4286 604619 }
4287 137432944 }
4288 780869 }
4289 272141 }
4290
4291 272141 void calc_darkroom_ffcs(mapscr* scr, int offx, int offy)
4292 {
4293 272141 word c = scr->numFFC();
4294
2/2
✓ Branch 0 taken 537406 times.
✓ Branch 1 taken 272141 times.
809547 for(int q = 0; q < c; ++q)
4295 {
4296 537406 newcombo const& cmb = combobuf[scr->ffcs[q].data];
4297
2/2
✓ Branch 0 taken 522598 times.
✓ Branch 1 taken 14808 times.
537406 if(cmb.type == cTORCH)
4298 {
4299 14808 int cx = scr->ffcs[q].x.getInt()+(scr->ffEffectWidth(q)/2)+offx;
4300 14808 int cy = (scr->ffcs[q].y.getInt())+(scr->ffEffectHeight(q)/2)+offy;
4301 14808 do_torch_combo(cmb, cx, cy, darkscr_bmp);
4302 14808 }
4303 537406 }
4304 272141 }
4305
4306 struct nearby_screen_t
4307 {
4308 int screen;
4309 int offx;
4310 int offy;
4311 screen_handles_t screen_handles;
4312 };
4313 typedef std::vector<nearby_screen_t> nearby_screens_t;
4314
4315 15487684 static nearby_screens_t get_nearby_screens_non_scrolling_region()
4316 {
4317 15487684 nearby_screens_t nearby_screens;
4318
4319 15487684 mapscr* base_scr = origin_scr;
4320
1/2
✓ Branch 0 taken 15487684 times.
✗ Branch 1 not taken.
15487684 auto& nearby_screen = nearby_screens.emplace_back();
4321 15487684 nearby_screen.screen = cur_screen;
4322
1/2
✓ Branch 0 taken 15487684 times.
✗ Branch 1 not taken.
15487684 nearby_screen.screen_handles = create_screen_handles(base_scr);
4323
4324 15487684 return nearby_screens;
4325
1/2
✓ Branch 0 taken 15487684 times.
✗ Branch 1 not taken.
15487684 }
4326
4327 48296 static nearby_screens_t get_nearby_screens_scrolling_region()
4328 {
4329 48296 nearby_screens_t nearby_screens;
4330
4331
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x0 = viewport.left() / 256;
4332
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x1 = (viewport.right() - 1) / 256;
4333
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y0 = viewport.top() / 176;
4334
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y1 = (viewport.bottom() - 1) / 176;
4335
4336
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x0 = std::clamp(screens_x0, 0, 15);
4337
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x1 = std::clamp(screens_x1, 0, 15);
4338
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y0 = std::clamp(screens_y0, 0, 8);
4339
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y1 = std::clamp(screens_y1, 0, 8);
4340
4341
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 79928 times.
128224 for (int x = screens_x0; x <= screens_x1; x++)
4342 {
4343
2/2
✓ Branch 0 taken 169672 times.
✓ Branch 1 taken 79928 times.
249600 for (int y = screens_y0; y <= screens_y1; y++)
4344 {
4345 169672 int screen = cur_screen + x + y*16;
4346
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!is_in_current_region(screen)) continue;
4347
4348
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 mapscr* base_scr = get_scr(screen);
4349
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!base_scr->is_valid()) continue;
4350
4351
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
4352
4353
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto& nearby_screen = nearby_screens.emplace_back();
4354 169672 nearby_screen.screen = screen;
4355 169672 nearby_screen.offx = offx;
4356 169672 nearby_screen.offy = offy;
4357
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 nearby_screen.screen_handles = create_screen_handles(base_scr);
4358 169672 }
4359 79928 }
4360
4361 48296 return nearby_screens;
4362
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 }
4363
4364 3658 static nearby_screens_t get_nearby_screens_smooth_maze()
4365 {
4366 3658 nearby_screens_t nearby_screens;
4367
4368
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x0 = viewport.left() / 256;
4369
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x1 = (viewport.right() - 1) / 256;
4370
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y0 = viewport.top() / 176;
4371
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y1 = (viewport.bottom() - 1) / 176;
4372
4373
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.left() < 0) screens_x0--;
4374
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.top() < 0) screens_y0--;
4375
4376
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 7308 times.
10966 for (int x = screens_x0; x <= screens_x1; x++)
4377 {
4378
2/2
✓ Branch 0 taken 18600 times.
✓ Branch 1 taken 7308 times.
25908 for (int y = screens_y0; y <= screens_y1; y++)
4379 {
4380 18600 int screen = -1;
4381 mapscr* base_scr;
4382 int offx, offy;
4383
4384 18600 mapscr* maze_scr = maze_state.scr;
4385 18600 int maze_screen = maze_scr->screen;
4386
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_x = get_region_relative_dx(maze_screen);
4387
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_y = get_region_relative_dy(maze_screen);
4388 18600 int maze_screen_dx = x - maze_screen_x;
4389 18600 int maze_screen_dy = y - maze_screen_y;
4390 18600 int exitdir = maze_scr->exitdir;
4391
4392 bool should_draw_maze_screen;
4393
2/2
✓ Branch 0 taken 9052 times.
✓ Branch 1 taken 9548 times.
18600 if (maze_state.lost)
4394 {
4395 9548 should_draw_maze_screen = true;
4396 9548 }
4397 else
4398 {
4399 9052 should_draw_maze_screen = true;
4400
4/6
✓ Branch 0 taken 9052 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6844 times.
✓ Branch 3 taken 2208 times.
✓ Branch 4 taken 6844 times.
✗ Branch 5 not taken.
9052 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != exitdir && XY_DELTA_TO_DIR(0, maze_screen_dy) != exitdir;
4401
2/2
✓ Branch 0 taken 3850 times.
✓ Branch 1 taken 5202 times.
9052 if (maze_state.enter_dir != dir_invalid)
4402
4/6
✓ Branch 0 taken 3850 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3304 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 3304 times.
✗ Branch 5 not taken.
3850 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != maze_state.enter_dir && XY_DELTA_TO_DIR(0, maze_screen_dy) != maze_state.enter_dir;
4403 }
4404
4405
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (should_draw_maze_screen)
4406 {
4407 16048 screen = maze_state.scr->screen;
4408 16048 base_scr = maze_state.scr;
4409
1/2
✓ Branch 0 taken 16048 times.
✗ Branch 1 not taken.
16048 std::tie(offx, offy) = translate_screen_coordinates_to_world(cur_screen + x + y*16);
4410 16048 }
4411
4412
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (screen == -1)
4413 {
4414 2552 screen = cur_screen + x + y*16;
4415
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!is_in_current_region(screen)) continue;
4416
4417
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 base_scr = get_scr(screen);
4418
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!base_scr->is_valid()) continue;
4419
4420
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 std::tie(offx, offy) = translate_screen_coordinates_to_world(screen);
4421 2552 }
4422
4423
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 auto& nearby_screen = nearby_screens.emplace_back();
4424 18600 nearby_screen.screen = screen;
4425 18600 nearby_screen.offx = offx;
4426 18600 nearby_screen.offy = offy;
4427
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 nearby_screen.screen_handles = create_screen_handles(base_scr);
4428 18600 }
4429 7308 }
4430
4431 3658 return nearby_screens;
4432
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 }
4433
4434 15539638 static nearby_screens_t get_nearby_screens()
4435 {
4436
4/4
✓ Branch 0 taken 9214 times.
✓ Branch 1 taken 15530424 times.
✓ Branch 2 taken 3658 times.
✓ Branch 3 taken 5556 times.
15539638 if (maze_state.active && maze_state.loopy)
4437 3658 return get_nearby_screens_smooth_maze();
4438
4439
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 15487684 times.
15535980 if (is_in_scrolling_region())
4440 48296 return get_nearby_screens_scrolling_region();
4441
4442 15487684 return get_nearby_screens_non_scrolling_region();
4443 15539638 }
4444
4445 202036787 static void for_every_nearby_screen(const nearby_screens_t& nearby_screens, const std::function <void (screen_handles_t, int, int, int)>& fn)
4446 {
4447
2/2
✓ Branch 0 taken 203821389 times.
✓ Branch 1 taken 202036787 times.
405858176 for (auto& nearby_screen : nearby_screens)
4448 203821389 fn(nearby_screen.screen_handles, nearby_screen.screen, nearby_screen.offx, nearby_screen.offy);
4449 202036787 }
4450
4451 124317104 static void draw_msgstr(byte layer, BITMAP* dest = nullptr)
4452 {
4453
2/2
✓ Branch 0 taken 15539638 times.
✓ Branch 1 taken 108777466 times.
124317104 if(layer != msgstr_layer) return;
4454
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 if(!dest) dest = framebuf;
4455
4456
2/2
✓ Branch 0 taken 679438 times.
✓ Branch 1 taken 14860200 times.
15539638 if(!(msg_bg_display_buf->clip))
4457 {
4458 679438 blit_msgstr_bg(dest,0,0,0,playing_field_offset,256,176);
4459 679438 }
4460
4461
2/2
✓ Branch 0 taken 679438 times.
✓ Branch 1 taken 14860200 times.
15539638 if(!(msg_portrait_display_buf->clip))
4462 {
4463 679438 blit_msgstr_prt(dest,0,0,0,playing_field_offset,256,176);
4464 679438 }
4465
4466
2/2
✓ Branch 0 taken 692845 times.
✓ Branch 1 taken 14846793 times.
15539638 if(!(msg_txt_display_buf->clip))
4467 {
4468 692845 blit_msgstr_fg(dest,0,0,0,playing_field_offset,256,176);
4469 692845 }
4470 124317104 }
4471
4472 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y);
4473
4474 62158552 static void set_draw_screen_clip(BITMAP* bmp)
4475 {
4476 62158552 set_clip_rect(bmp, draw_screen_clip_rect_x1, draw_screen_clip_rect_y1, draw_screen_clip_rect_x2, draw_screen_clip_rect_y2);
4477 62158552 }
4478
4479 46118658 void draw_screen(bool showhero, bool runGeneric)
4480 {
4481 46118658 clear_info_bmp();
4482
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46118658 times.
46118658 if((GameFlags & (GAMEFLAG_SCRIPTMENU_ACTIVE|GAMEFLAG_F6SCRIPT_ACTIVE))!=0)
4483 {
4484 FFCore.doScriptMenuDraws();
4485 return;
4486 }
4487
4488
2/2
✓ Branch 0 taken 31180560 times.
✓ Branch 1 taken 14938098 times.
46118658 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_PRE_DRAW);
4489
4490 46118658 clear_bitmap(framebuf);
4491 46118658 clear_clip_rect(framebuf);
4492
4493 46118658 int32_t cmby2=0;
4494
4495 // Draw some background layers
4496 46118658 clear_bitmap(scrollbuf);
4497
4498 46118658 auto nearby_screens = get_nearby_screens();
4499
4500 // Handle layer 2/3 possibly being background layers.
4501
1/2
✓ Branch 0 taken 46118658 times.
✗ Branch 1 not taken.
61794614 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4502 15675956 mapscr* base_scr = screen_handles[0].base_scr;
4503
2/2
✓ Branch 0 taken 15548674 times.
✓ Branch 1 taken 127282 times.
15675956 if (XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4504 127282 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4505 15675956 });
4506
4507
2/2
✓ Branch 0 taken 127282 times.
✓ Branch 1 taken 45991376 times.
46118658 if (XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4508 {
4509
1/2
✓ Branch 0 taken 127282 times.
✗ Branch 1 not taken.
127282 do_layer_primitives(scrollbuf, 2);
4510
1/2
✓ Branch 0 taken 127282 times.
✗ Branch 1 not taken.
127282 particles.draw(scrollbuf, true, 2);
4511 127282 }
4512
2/2
✓ Branch 0 taken 15539638 times.
✓ Branch 1 taken 30579020 times.
46118658 _do_current_ffc_layer(scrollbuf, -2);
4513
2/2
✓ Branch 0 taken 127282 times.
✓ Branch 1 taken 15412356 times.
15539638 if (XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4514
1/2
✓ Branch 0 taken 127282 times.
✗ Branch 1 not taken.
127282 draw_msgstr(2, scrollbuf);
4515
4516
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
31215594 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4517 15675956 mapscr* base_scr = screen_handles[0].base_scr;
4518
2/2
✓ Branch 0 taken 15583296 times.
✓ Branch 1 taken 92660 times.
15675956 if (XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4519 92660 do_layer(scrollbuf, 0, screen_handles[3], offx, offy);
4520 15675956 });
4521
4522
2/2
✓ Branch 0 taken 92660 times.
✓ Branch 1 taken 15446978 times.
15539638 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4523 {
4524
1/2
✓ Branch 0 taken 92660 times.
✗ Branch 1 not taken.
92660 do_layer_primitives(scrollbuf, 3);
4525
1/2
✓ Branch 0 taken 92660 times.
✗ Branch 1 not taken.
92660 particles.draw(scrollbuf, true, 3);
4526 92660 }
4527
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 _do_current_ffc_layer(scrollbuf, -3);
4528
2/2
✓ Branch 0 taken 92660 times.
✓ Branch 1 taken 15446978 times.
15539638 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4529
1/2
✓ Branch 0 taken 92660 times.
✗ Branch 1 not taken.
92660 draw_msgstr(3, scrollbuf);
4530
4531 // Draw the main combo screens ("layer 0").
4532
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
31215594 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4533 15675956 mapscr* base_scr = screen_handles[0].base_scr;
4534
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15675956 times.
15675956 if (lenscheck(base_scr, 0))
4535 {
4536 15675956 putscr(base_scr, scrollbuf, offx, offy + playing_field_offset);
4537 15675956 }
4538 15675956 });
4539
4540
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15539638 times.
15539638 if (lenscheck(hero_scr, 0))
4541 {
4542
2/2
✓ Branch 0 taken 466049 times.
✓ Branch 1 taken 15073589 times.
15539638 if(!get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4543
3/4
✓ Branch 0 taken 466049 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4136 times.
✓ Branch 3 taken 461913 times.
470185 if(mblock2.draw(scrollbuf,0))
4544
1/2
✓ Branch 0 taken 4136 times.
✗ Branch 1 not taken.
4136 do_primitives(scrollbuf, SPLAYER_MOVINGBLOCK);
4545 15539638 }
4546
4547 // Lens hints, then primitives, then particles.
4548
6/10
✓ Branch 0 taken 15529609 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 15529609 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 15529609 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 5876 times.
✓ Branch 9 taken 4153 times.
15539638 if((lensclk || (get_debug() && zc_getkey(KEY_L))) && !get_qr(qr_OLDLENSORDER))
4549 {
4550
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 draw_lens_under(scrollbuf, false);
4551
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4552 5876 }
4553
4554
2/4
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15539638 times.
✗ Branch 3 not taken.
15539638 if(show_layers[0] && lenscheck(hero_scr,0))
4555
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 do_primitives(scrollbuf, 0);
4556
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 particles.draw(scrollbuf, true, 0);
4557
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 _do_current_ffc_layer(scrollbuf, 0);
4558
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 draw_msgstr(0, scrollbuf);
4559
4560
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 set_draw_screen_clip(scrollbuf);
4561
4562
2/2
✓ Branch 0 taken 15196379 times.
✓ Branch 1 taken 343259 times.
15539638 if(!(get_qr(qr_LAYER12UNDERCAVE)))
4563 {
4564
4/4
✓ Branch 0 taken 15194505 times.
✓ Branch 1 taken 1874 times.
✓ Branch 2 taken 53632 times.
✓ Branch 3 taken 15106121 times.
30356132 if(showhero &&
4565
4/6
✓ Branch 0 taken 15194505 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15159753 times.
✓ Branch 3 taken 34752 times.
✓ Branch 4 taken 15159753 times.
✗ Branch 5 not taken.
15194505 ((Hero.getAction()==climbcovertop)||(Hero.getAction()==climbcoverbottom)))
4566 {
4567
3/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 53632 times.
✓ Branch 3 taken 34752 times.
88384 if(Hero.getAction()==climbcovertop)
4568 {
4569 34752 cmby2=16;
4570 34752 }
4571
2/4
✓ Branch 0 taken 53632 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53632 times.
53632 else if(Hero.getAction()==climbcoverbottom)
4572 {
4573 53632 cmby2=-16;
4574 53632 }
4575
4576
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw2(scrollbuf,true);
4577
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 Hero.draw(scrollbuf);
4578
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw(scrollbuf,true);
4579
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccx = (int32_t)Hero.getClimbCoverX();
4580
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccy = (int32_t)Hero.getClimbCoverY();
4581
4582
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4583
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4584
4585
4/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✓ Branch 5 taken 73152 times.
88384 if(int32_t(Hero.getX())&15)
4586 {
4587
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4588
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4589 15232 }
4590 88384 }
4591 15196379 }
4592
4593
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
31215594 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4594 15675956 do_layer(scrollbuf, 0, screen_handles[1], offx, offy); // LAYER 1
4595 15675956 });
4596
4597
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 do_layer_primitives(scrollbuf, 1);
4598
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 particles.draw(scrollbuf, true, 1);
4599
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 _do_current_ffc_layer(scrollbuf, 1);
4600
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 draw_msgstr(1, scrollbuf);
4601
4602 // Handle layer 2 NOT being used as background layers.
4603
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
31215594 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4604 15675956 mapscr* base_scr = screen_handles[0].base_scr;
4605
2/2
✓ Branch 0 taken 127282 times.
✓ Branch 1 taken 15548674 times.
15675956 if (!XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4606 15548674 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4607 15675956 });
4608
4609
2/2
✓ Branch 0 taken 15412356 times.
✓ Branch 1 taken 127282 times.
15539638 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4610 {
4611
1/2
✓ Branch 0 taken 15412356 times.
✗ Branch 1 not taken.
15412356 do_layer_primitives(scrollbuf, 2);
4612
1/2
✓ Branch 0 taken 15412356 times.
✗ Branch 1 not taken.
15412356 particles.draw(scrollbuf, true, 2);
4613 15412356 }
4614
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 _do_current_ffc_layer(scrollbuf, 2);
4615
2/2
✓ Branch 0 taken 15412356 times.
✓ Branch 1 taken 127282 times.
15539638 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4616
1/2
✓ Branch 0 taken 15412356 times.
✗ Branch 1 not taken.
15412356 draw_msgstr(2, scrollbuf);
4617
4618
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 do_primitives(scrollbuf, SPLAYER_FFC_DRAW);
4619
4620
2/2
✓ Branch 0 taken 343259 times.
✓ Branch 1 taken 15196379 times.
15539638 if(get_qr(qr_LAYER12UNDERCAVE))
4621 {
4622
2/4
✓ Branch 0 taken 343259 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 343259 times.
686518 if(showhero &&
4623
3/6
✓ Branch 0 taken 343259 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 343259 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 343259 times.
✗ Branch 5 not taken.
343259 ((Hero.getAction()==climbcovertop)||(Hero.getAction()==climbcoverbottom)))
4624 {
4625 if(Hero.getAction()==climbcovertop)
4626 {
4627 cmby2=16;
4628 }
4629 else if(Hero.getAction()==climbcoverbottom)
4630 {
4631 cmby2=-16;
4632 }
4633
4634 decorations.draw2(scrollbuf,true);
4635 Hero.draw(scrollbuf);
4636 decorations.draw(scrollbuf,true);
4637 int32_t ccx = (int32_t)(Hero.getClimbCoverX());
4638 int32_t ccy = (int32_t)(Hero.getClimbCoverY());
4639
4640 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4641 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4642
4643 if(int32_t(Hero.getX())&15)
4644 {
4645 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4646 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4647 }
4648 }
4649 343259 }
4650
4651
2/2
✓ Branch 0 taken 466049 times.
✓ Branch 1 taken 15073589 times.
15539638 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4652 {
4653
1/2
✓ Branch 0 taken 15073589 times.
✗ Branch 1 not taken.
30283496 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4654 15209907 do_layer(scrollbuf, -2, screen_handles[0], offx, offy); // push blocks!
4655
2/2
✓ Branch 0 taken 14478921 times.
✓ Branch 1 taken 730986 times.
15209907 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
4656 {
4657 730986 do_layer(scrollbuf, -2, screen_handles[1], offx, offy); // push blocks!
4658 730986 do_layer(scrollbuf, -2, screen_handles[2], offx, offy); // push blocks!
4659 730986 }
4660 15209907 });
4661
4662
1/2
✓ Branch 0 taken 15073589 times.
✗ Branch 1 not taken.
15073589 do_primitives(scrollbuf, SPLAYER_PUSHBLOCK);
4663 15073589 }
4664
4665 // Show walkflags cheat
4666
2/4
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 15539638 times.
15539638 if (show_walkflags || show_effectflags)
4667 {
4668 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4669 do_walkflags(screen_handles, offx, offy);
4670 do_effectflags(screen_handles[0].base_scr, offx, offy);
4671 });
4672
4673 do_walkflags(0, 0);
4674 }
4675
4676
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 putscrdoors(nearby_screens, scrollbuf, 0, playing_field_offset);
4677
4678 // Lens hints, doors etc.
4679
4/8
✓ Branch 0 taken 15529609 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 15529609 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 15529609 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
15539638 if(lensclk || (get_debug() && zc_getkey(KEY_L)))
4680 {
4681
2/2
✓ Branch 0 taken 4153 times.
✓ Branch 1 taken 5876 times.
10029 if(get_qr(qr_OLDLENSORDER))
4682 {
4683
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 draw_lens_under(scrollbuf, false);
4684
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4685 4153 }
4686
4687
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 draw_lens_under(scrollbuf, true);
4688
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_2);
4689 10029 }
4690
4691 // Blit those layers onto framebuf
4692
4693
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 set_draw_screen_clip(framebuf);
4694
4695
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 blit(scrollbuf, framebuf, 0, 0, 0, 0, 256, 232);
4696
4697 // After this point, scrollbuf is no longer drawn to - so things like dosubscr have access to a "partially rendered" frame.
4698 // I think only used for COOLSCROLL==0? Seems like a silly feature...
4699
4700 // Draw the subscreen, without clipping
4701
2/2
✓ Branch 0 taken 9251384 times.
✓ Branch 1 taken 6288254 times.
15539638 if(!get_qr(qr_SUBSCREENOVERSPRITES))
4702 {
4703 9251384 bool dotime = false;
4704
4/6
✓ Branch 0 taken 9251384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3412853 times.
✓ Branch 3 taken 5838531 times.
✓ Branch 4 taken 3412853 times.
✗ Branch 5 not taken.
9251384 if (replay_version_check(22)) dotime = game->should_show_time();
4705
1/2
✓ Branch 0 taken 9251384 times.
✗ Branch 1 not taken.
9251384 put_passive_subscr(framebuf, 0, 0, dotime, sspUP);
4706 9251384 }
4707
4708 // Draw some sprites onto framebuf
4709
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 set_clip_rect(framebuf,0,0,256,232);
4710
4711
2/2
✓ Branch 0 taken 99496 times.
✓ Branch 1 taken 15440142 times.
15539638 if(!(pricesdisplaybuf->clip))
4712 {
4713
1/2
✓ Branch 0 taken 99496 times.
✗ Branch 1 not taken.
99496 masked_blit(pricesdisplaybuf,framebuf,0,0,0,playing_field_offset,256,176);
4714 99496 }
4715
4716
5/6
✓ Branch 0 taken 15494012 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 15487684 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
15539638 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
4717 add_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
4718
4719
8/10
✓ Branch 0 taken 15537764 times.
✓ Branch 1 taken 1874 times.
✓ Branch 2 taken 15537764 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15503012 times.
✓ Branch 5 taken 34752 times.
✓ Branch 6 taken 15503012 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15449380 times.
✓ Branch 9 taken 53632 times.
15539638 if(showhero && ((Hero.getAction()!=climbcovertop)&&(Hero.getAction()!=climbcoverbottom)))
4720 {
4721
1/2
✓ Branch 0 taken 15449380 times.
✗ Branch 1 not taken.
15449380 Hero.draw_under(framebuf);
4722
4723
3/4
✓ Branch 0 taken 15449380 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 141385 times.
✓ Branch 3 taken 15307995 times.
15449380 if(Hero.isSwimming())
4724 {
4725
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw2(framebuf,true);
4726
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 Hero.draw(framebuf);
4727
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw(framebuf,true);
4728 141385 }
4729 15449380 }
4730
4731
2/2
✓ Branch 0 taken 26095 times.
✓ Branch 1 taken 15513543 times.
15539638 if(drawguys)
4732 {
4733
4/4
✓ Branch 0 taken 1982674 times.
✓ Branch 1 taken 13530869 times.
✓ Branch 2 taken 991089 times.
✓ Branch 3 taken 991585 times.
15513543 if(get_qr(qr_NOFLICKER) || (frame&1))
4734 {
4735 // Just clips sprites if in a repeating, smooth maze.
4736
2/2
✓ Branch 0 taken 14512744 times.
✓ Branch 1 taken 9214 times.
14521958 bool do_clip = maze_state.active && maze_state.loopy;
4737
4738
3/4
✓ Branch 0 taken 23627100 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9105142 times.
✓ Branch 3 taken 14521958 times.
23627100 for(int32_t i=0; i<Ewpns.Count(); i++)
4739 {
4740
3/4
✓ Branch 0 taken 9105142 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 197943 times.
✓ Branch 3 taken 8907199 times.
9105142 if(((weapon *)Ewpns.spr(i))->behind)
4741
2/4
✓ Branch 0 taken 197943 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 197943 times.
✗ Branch 3 not taken.
197943 Ewpns.spr(i)->draw(framebuf);
4742 9105142 }
4743
1/2
✓ Branch 0 taken 14521958 times.
✗ Branch 1 not taken.
14521958 do_primitives(framebuf, SPLAYER_EWEAP_BEHIND_DRAW);
4744
4745
3/4
✓ Branch 0 taken 19197054 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4675096 times.
✓ Branch 3 taken 14521958 times.
19197054 for(int32_t i=0; i<Lwpns.Count(); i++)
4746 {
4747
3/4
✓ Branch 0 taken 4675096 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3205 times.
✓ Branch 3 taken 4671891 times.
4675096 if(((weapon *)Lwpns.spr(i))->behind)
4748
2/4
✓ Branch 0 taken 3205 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3205 times.
✗ Branch 3 not taken.
3205 Lwpns.spr(i)->draw(framebuf);
4749 4675096 }
4750
1/2
✓ Branch 0 taken 14521958 times.
✗ Branch 1 not taken.
14521958 do_primitives(framebuf, SPLAYER_LWEAP_BEHIND_DRAW);
4751
4752
6/6
✓ Branch 0 taken 9785094 times.
✓ Branch 1 taken 4736864 times.
✓ Branch 2 taken 1348300 times.
✓ Branch 3 taken 8436794 times.
✓ Branch 4 taken 674011 times.
✓ Branch 5 taken 674289 times.
14521958 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4753 {
4754
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 9107147 times.
9110805 if (do_clip)
4755
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.drawshadow_smooth_maze(framebuf,get_qr(qr_TRANSSHADOWS)!=0);
4756 else
4757
1/2
✓ Branch 0 taken 9107147 times.
✗ Branch 1 not taken.
9107147 guys.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS)!=0,true);
4758 9110805 }
4759
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518300 times.
14521958 if (do_clip)
4760
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.draw_smooth_maze(framebuf);
4761 else
4762
1/2
✓ Branch 0 taken 14518300 times.
✗ Branch 1 not taken.
14518300 guys.draw(framebuf,true);
4763
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518300 times.
14521958 if (do_clip)
4764 {
4765 3658 int maze_screen = maze_state.scr->screen;
4766
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4767
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(framebuf, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4768 3658 }
4769
1/2
✓ Branch 0 taken 14521958 times.
✗ Branch 1 not taken.
14521958 do_primitives(framebuf, SPLAYER_NPC_DRAW);
4770
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518300 times.
14521958 if (do_clip)
4771
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(framebuf);
4772
4773
1/2
✓ Branch 0 taken 14521958 times.
✗ Branch 1 not taken.
14521958 chainlinks.draw(framebuf,true);
4774
1/2
✓ Branch 0 taken 14521958 times.
✗ Branch 1 not taken.
14521958 do_primitives(framebuf, SPLAYER_CHAINLINK_DRAW);
4775 //Lwpns.draw(framebuf,true);
4776
4777
3/4
✓ Branch 0 taken 23627100 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9105142 times.
✓ Branch 3 taken 14521958 times.
23627100 for(int32_t i=0; i<Ewpns.Count(); i++)
4778 {
4779
3/4
✓ Branch 0 taken 9105142 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8907199 times.
✓ Branch 3 taken 197943 times.
9105142 if(!((weapon *)Ewpns.spr(i))->behind)
4780
2/4
✓ Branch 0 taken 8907199 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8907199 times.
✗ Branch 3 not taken.
8907199 Ewpns.spr(i)->draw(framebuf);
4781 9105142 }
4782
1/2
✓ Branch 0 taken 14521958 times.
✗ Branch 1 not taken.
14521958 do_primitives(framebuf, SPLAYER_EWEAP_FRONT_DRAW);
4783
4784
3/4
✓ Branch 0 taken 19197054 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4675096 times.
✓ Branch 3 taken 14521958 times.
19197054 for(int32_t i=0; i<Lwpns.Count(); i++)
4785 {
4786
3/4
✓ Branch 0 taken 4675096 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4671891 times.
✓ Branch 3 taken 3205 times.
4675096 if(!((weapon *)Lwpns.spr(i))->behind)
4787
2/4
✓ Branch 0 taken 4671891 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4671891 times.
✗ Branch 3 not taken.
4671891 Lwpns.spr(i)->draw(framebuf);
4788 4675096 }
4789
1/2
✓ Branch 0 taken 14521958 times.
✗ Branch 1 not taken.
14521958 do_primitives(framebuf, SPLAYER_LWEAP_FRONT_DRAW);
4790
4791
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518300 times.
14521958 if (do_clip)
4792
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 items.draw_smooth_maze(framebuf);
4793 else
4794
1/2
✓ Branch 0 taken 14518300 times.
✗ Branch 1 not taken.
14518300 items.draw(framebuf,true);
4795
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518300 times.
14521958 if (do_clip)
4796 {
4797 3658 int maze_screen = maze_state.scr->screen;
4798
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4799
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(framebuf, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4800 3658 }
4801
1/2
✓ Branch 0 taken 14521958 times.
✗ Branch 1 not taken.
14521958 do_primitives(framebuf, SPLAYER_ITEMSPRITE_DRAW);
4802
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518300 times.
14521958 if (do_clip)
4803
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(framebuf);
4804 14521958 }
4805 else
4806 {
4807
3/4
✓ Branch 0 taken 1496957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991585 times.
1496957 for(int32_t i=0; i<Ewpns.Count(); i++)
4808 {
4809
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✓ Branch 3 taken 496727 times.
505372 if(((weapon *)Ewpns.spr(i))->behind)
4810
2/4
✓ Branch 0 taken 8645 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✗ Branch 3 not taken.
8645 Ewpns.spr(i)->draw(framebuf);
4811 505372 }
4812
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_EWEAP_BEHIND_DRAW);
4813
4814
3/4
✓ Branch 0 taken 1222731 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✓ Branch 3 taken 991585 times.
1222731 for(int32_t i=0; i<Lwpns.Count(); i++)
4815 {
4816
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 231146 times.
231146 if(((weapon *)Lwpns.spr(i))->behind)
4817 Lwpns.spr(i)->draw(framebuf);
4818 231146 }
4819
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_LWEAP_BEHIND_DRAW);
4820
4821
3/4
✓ Branch 0 taken 228620 times.
✓ Branch 1 taken 762965 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 228620 times.
991585 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4822 {
4823
1/2
✓ Branch 0 taken 228620 times.
✗ Branch 1 not taken.
228620 guys.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS)!=0,true);
4824 228620 }
4825
4826
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 items.draw(framebuf,false);
4827
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_ITEMSPRITE_DRAW);
4828
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 chainlinks.draw(framebuf,false);
4829
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_CHAINLINK_DRAW);
4830 //Lwpns.draw(framebuf,false);
4831
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 guys.draw(framebuf,false);
4832
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_NPC_DRAW);
4833
4834
3/4
✓ Branch 0 taken 1496957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991585 times.
1496957 for(int32_t i=0; i<Ewpns.Count(); i++)
4835 {
4836
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✓ Branch 3 taken 8645 times.
505372 if(!((weapon *)Ewpns.spr(i))->behind)
4837 {
4838
2/4
✓ Branch 0 taken 496727 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✗ Branch 3 not taken.
496727 Ewpns.spr(i)->draw(framebuf);
4839 496727 }
4840 505372 }
4841
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_EWEAP_FRONT_DRAW);
4842
4843
3/4
✓ Branch 0 taken 1222731 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✓ Branch 3 taken 991585 times.
1222731 for(int32_t i=0; i<Lwpns.Count(); i++)
4844 {
4845
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✗ Branch 3 not taken.
231146 if(!((weapon *)Lwpns.spr(i))->behind)
4846 {
4847
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✗ Branch 3 not taken.
231146 Lwpns.spr(i)->draw(framebuf);
4848 231146 }
4849 231146 }
4850
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_LWEAP_FRONT_DRAW);
4851 }
4852
4853
1/2
✓ Branch 0 taken 15513543 times.
✗ Branch 1 not taken.
15513543 guys.draw2(framebuf,true);
4854 15513543 }
4855
4856
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15539638 times.
15539638 if(mirror_portal.destdmap > -1)
4857 mirror_portal.draw(framebuf);
4858
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 portals.draw(framebuf,true);
4859
4860
8/10
✓ Branch 0 taken 15537764 times.
✓ Branch 1 taken 1874 times.
✓ Branch 2 taken 15537764 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15503012 times.
✓ Branch 5 taken 34752 times.
✓ Branch 6 taken 15503012 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15449380 times.
✓ Branch 9 taken 53632 times.
15539638 if(showhero && ((Hero.getAction()!=climbcovertop)&& (Hero.getAction()!=climbcoverbottom)))
4861 {
4862
2/2
✓ Branch 0 taken 14989747 times.
✓ Branch 1 taken 459633 times.
15449380 if(get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4863 {
4864
1/2
✓ Branch 0 taken 14989747 times.
✗ Branch 1 not taken.
14989747 mblock2.draw(framebuf,-1);
4865
1/2
✓ Branch 0 taken 14989747 times.
✗ Branch 1 not taken.
14989747 do_primitives(framebuf, SPLAYER_MOVINGBLOCK);
4866 14989747 }
4867
3/4
✓ Branch 0 taken 15449380 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15307995 times.
✓ Branch 3 taken 141385 times.
15449380 if(!Hero.isSwimming())
4868 {
4869
8/12
✓ Branch 0 taken 15307995 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15307995 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15288825 times.
✓ Branch 5 taken 19170 times.
✓ Branch 6 taken 15288825 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15288825 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1370 times.
✓ Branch 11 taken 15306625 times.
15307995 if((Hero.getZ()>0 || Hero.getFakeZ()>0) &&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4870 {
4871
2/2
✓ Branch 0 taken 18485 times.
✓ Branch 1 taken 15289510 times.
15307995 Hero.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS)!=0);
4872 18485 }
4873
4874
6/8
✓ Branch 0 taken 15307995 times.
✓ Branch 1 taken 15289510 times.
✓ Branch 2 taken 15307995 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15307995 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15293931 times.
✓ Branch 7 taken 14064 times.
18485 if(Hero.getZ() <= (zfix)zinit.jump_hero_layer_threshold)
4875 {
4876
1/2
✓ Branch 0 taken 15293931 times.
✗ Branch 1 not taken.
15293931 decorations.draw2(framebuf,true);
4877
1/2
✓ Branch 0 taken 15293931 times.
✗ Branch 1 not taken.
15293931 Hero.draw(framebuf);
4878
1/2
✓ Branch 0 taken 15293931 times.
✗ Branch 1 not taken.
15293931 decorations.draw(framebuf,true);
4879 15293931 }
4880 15307995 }
4881 15449380 }
4882
4883
3/4
✓ Branch 0 taken 54880091 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 39340453 times.
✓ Branch 3 taken 15539638 times.
54880091 for(int32_t i=0; i<guys.Count(); i++)
4884 {
4885
3/4
✓ Branch 0 taken 39340453 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15945464 times.
✓ Branch 3 taken 23394989 times.
39340453 if(((enemy*)guys.spr(i))->family == eeWALK)
4886 {
4887
3/4
✓ Branch 0 taken 15945464 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7295 times.
✓ Branch 3 taken 15938169 times.
15945464 if(((eStalfos*)guys.spr(i))->hashero)
4888 {
4889
2/4
✓ Branch 0 taken 7295 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7295 times.
✗ Branch 3 not taken.
7295 guys.spr(i)->draw(framebuf);
4890 7295 }
4891 15945464 }
4892
4893
3/4
✓ Branch 0 taken 39340453 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 507162 times.
✓ Branch 3 taken 38833291 times.
39340453 if(((enemy*)guys.spr(i))->family == eeWALLM)
4894 {
4895
3/4
✓ Branch 0 taken 507162 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✓ Branch 3 taken 505833 times.
507162 if(((eWallM*)guys.spr(i))->hashero)
4896 {
4897
2/4
✓ Branch 0 taken 1329 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✗ Branch 3 not taken.
1329 guys.spr(i)->draw(framebuf);
4898 1329 }
4899 507162 }
4900
4901
11/20
✓ Branch 0 taken 39340453 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 39340453 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 39340453 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 39340453 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 39340453 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 39340453 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 39340453 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 39340453 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 39340453 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1342694 times.
✓ Branch 19 taken 37997759 times.
39340453 if(guys.spr(i)->z+guys.spr(i)->fakez > Hero.getZ()+Hero.getFakeZ())
4902 {
4903 //Jumping enemies in front of Hero.
4904
2/4
✓ Branch 0 taken 1342694 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1342694 times.
✗ Branch 3 not taken.
1342694 guys.spr(i)->draw(framebuf);
4905 1342694 }
4906
1/2
✓ Branch 0 taken 39340453 times.
✗ Branch 1 not taken.
39340453 do_primitives(framebuf, SPLAYER_NPC_ABOVEPLAYER_DRAW);
4907 39340453 }
4908
4909 // Draw some layers onto framebuf
4910
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 set_draw_screen_clip(framebuf);
4911
5/6
✓ Branch 0 taken 15494012 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 15487684 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
15539638 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
4912 add_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
4913
4914 // Handle layer 3 NOT being used as background layers.
4915
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
31215594 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4916 15675956 mapscr* base_scr = screen_handles[0].base_scr;
4917
2/2
✓ Branch 0 taken 92660 times.
✓ Branch 1 taken 15583296 times.
15675956 if (!XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4918 15583296 do_layer(framebuf, 0, screen_handles[3], offx, offy);
4919 15675956 });
4920
4921
2/2
✓ Branch 0 taken 15446978 times.
✓ Branch 1 taken 92660 times.
15539638 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4922 {
4923
1/2
✓ Branch 0 taken 15446978 times.
✗ Branch 1 not taken.
15446978 do_layer_primitives(framebuf, 3);
4924
1/2
✓ Branch 0 taken 15446978 times.
✗ Branch 1 not taken.
15446978 particles.draw(framebuf, true, 3);
4925 15446978 }
4926
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 _do_current_ffc_layer(framebuf, 3);
4927
2/2
✓ Branch 0 taken 15446978 times.
✓ Branch 1 taken 92660 times.
15539638 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4928
1/2
✓ Branch 0 taken 15446978 times.
✗ Branch 1 not taken.
15446978 draw_msgstr(3);
4929
4930
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
31215594 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4931 15675956 do_layer(framebuf, 0, screen_handles[4], offx, offy);
4932 15675956 });
4933
4934
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 do_layer_primitives(framebuf, 4);
4935
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 particles.draw(framebuf, true, 4);
4936
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 _do_current_ffc_layer(framebuf, 4);
4937
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 draw_msgstr(4);
4938
4939
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
31215594 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4940 15675956 do_layer(framebuf, -1, screen_handles[0], offx, offy);
4941
2/2
✓ Branch 0 taken 14400201 times.
✓ Branch 1 taken 1275755 times.
15675956 if (get_qr(qr_OVERHEAD_COMBOS_L1_L2))
4942 {
4943 1275755 do_layer(framebuf, -1, screen_handles[1], offx, offy);
4944 1275755 do_layer(framebuf, -1, screen_handles[2], offx, offy);
4945 1275755 }
4946 15675956 });
4947
4948
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 do_primitives(framebuf, SPLAYER_OVERHEAD_CMB);
4949
4950 // Draw some flying sprites onto framebuf
4951
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 clear_clip_rect(framebuf);
4952
5/6
✓ Branch 0 taken 15494012 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 15487684 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
15539638 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
4953 add_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
4954
4955 //Jumping Hero and jumping enemies are drawn on this layer.
4956
5/8
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15539638 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15539638 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 14064 times.
✓ Branch 7 taken 15525574 times.
15539638 if(Hero.getZ() > (zfix)zinit.jump_hero_layer_threshold)
4957 {
4958
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 decorations.draw2(framebuf,false);
4959
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 Hero.draw(framebuf);
4960
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 chainlinks.draw(framebuf,true);
4961
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 do_primitives(framebuf, SPLAYER_CHAINLINK_DRAW);
4962
4963
3/4
✓ Branch 0 taken 16806 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✓ Branch 3 taken 14064 times.
16806 for(int32_t i=0; i<Lwpns.Count(); i++)
4964 {
4965
9/16
✓ Branch 0 taken 2742 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2742 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2742 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2742 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2742 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2742 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 239 times.
✓ Branch 15 taken 2503 times.
2742 if(Lwpns.spr(i)->z+Lwpns.spr(i)->fakez > (zfix)zinit.jump_hero_layer_threshold)
4966 {
4967
2/4
✓ Branch 0 taken 239 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 239 times.
✗ Branch 3 not taken.
239 Lwpns.spr(i)->draw(framebuf);
4968 239 }
4969 2742 }
4970
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 do_primitives(framebuf, SPLAYER_LWEAP_ABOVE_DRAW);
4971
4972
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 decorations.draw(framebuf,false);
4973 14064 }
4974
4975
5/6
✓ Branch 0 taken 3288982 times.
✓ Branch 1 taken 12250656 times.
✓ Branch 2 taken 44334247 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 32083591 times.
✓ Branch 5 taken 12250656 times.
47623229 if(!get_qr(qr_ENEMIESZAXIS)) for(int32_t i=0; i<guys.Count(); i++)
4976 {
4977
13/22
✓ Branch 0 taken 32083591 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32083591 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 27177493 times.
✓ Branch 5 taken 4906098 times.
✓ Branch 6 taken 27177493 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 27177493 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 27177493 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 27177493 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 27177493 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 27177493 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 27177493 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 6568 times.
✓ Branch 21 taken 27170925 times.
32083591 if((isflier(guys.spr(i)->id)) || (guys.spr(i)->z+guys.spr(i)->fakez) > (zfix)zinit.jump_hero_layer_threshold)
4978 {
4979
2/4
✓ Branch 0 taken 4912666 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4912666 times.
✗ Branch 3 not taken.
4912666 guys.spr(i)->draw(framebuf);
4980 4912666 }
4981 44334247 }
4982 else
4983 {
4984
3/4
✓ Branch 0 taken 10545844 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7256862 times.
✓ Branch 3 taken 3288982 times.
10545844 for(int32_t i=0; i<guys.Count(); i++)
4985 {
4986
13/22
✓ Branch 0 taken 7256862 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7256862 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6081157 times.
✓ Branch 5 taken 1175705 times.
✓ Branch 6 taken 6081157 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6081157 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 6081157 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 5594346 times.
✓ Branch 13 taken 486811 times.
✓ Branch 14 taken 5594346 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 5594346 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 5594346 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 5594346 times.
7256862 if((isflier(guys.spr(i)->id)) || guys.spr(i)->z > 0 || guys.spr(i)->fakez > 0)
4987 {
4988
2/4
✓ Branch 0 taken 1662516 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1662516 times.
✗ Branch 3 not taken.
1662516 guys.spr(i)->draw(framebuf);
4989 1662516 }
4990 7256862 }
4991 }
4992
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 do_primitives(framebuf, SPLAYER_NPC_AIRBORNE_DRAW);
4993
4994 // Draw the Moving Fairy above layer 3
4995
3/4
✓ Branch 0 taken 18684732 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3145094 times.
✓ Branch 3 taken 15539638 times.
18684732 for(int32_t i=0; i<items.Count(); i++)
4996
6/8
✓ Branch 0 taken 3145094 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 69867 times.
✓ Branch 3 taken 3075227 times.
✓ Branch 4 taken 69867 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 60153 times.
✓ Branch 7 taken 9714 times.
3205247 if(itemsbuf[items.spr(i)->id].family == itype_fairy && itemsbuf[items.spr(i)->id].misc3)
4997
2/4
✓ Branch 0 taken 60153 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 60153 times.
✗ Branch 3 not taken.
60153 items.spr(i)->draw(framebuf);
4998
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 do_primitives(framebuf, SPLAYER_FAIRYITEM_DRAW);
4999
5000 // Draw some layers onto framebuf
5001
5002
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 set_draw_screen_clip(framebuf);
5003
5004
2/2
✓ Branch 0 taken 15525286 times.
✓ Branch 1 taken 14352 times.
15539638 if (lightbeam_present)
5005 {
5006 14352 color_map = &trans_table2;
5007
2/2
✓ Branch 0 taken 13114 times.
✓ Branch 1 taken 1238 times.
14352 if(get_qr(qr_LIGHTBEAM_TRANSPARENT))
5008
1/2
✓ Branch 0 taken 13114 times.
✗ Branch 1 not taken.
13114 draw_trans_sprite(framebuf, lightbeam_bmp, 0, playing_field_offset);
5009 else
5010
1/2
✓ Branch 0 taken 1238 times.
✗ Branch 1 not taken.
1238 masked_blit(lightbeam_bmp, framebuf, 0, 0, 0, playing_field_offset, 256, 176);
5011 14352 color_map = &trans_table;
5012 14352 }
5013
5014
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
31215594 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5015 15675956 do_layer(framebuf, 0, screen_handles[5], offx, offy);
5016 15675956 });
5017
5018
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 do_layer_primitives(framebuf, 5);
5019
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 particles.draw(framebuf, true, 5);
5020
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 _do_current_ffc_layer(framebuf, 5);
5021
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 draw_msgstr(5);
5022
5023
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 _do_current_ffc_layer(framebuf, -1); // 'overhead' freeform combos
5024
5025
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 do_primitives(framebuf, SPLAYER_OVERHEAD_FFC);
5026
5027
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
31215594 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5028 15675956 do_layer(framebuf, 0, screen_handles[6], offx, offy);
5029 15675956 });
5030
5031
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 do_layer_primitives(framebuf, 6);
5032
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 particles.draw(framebuf, true, 6);
5033
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 _do_current_ffc_layer(framebuf, 6);
5034
5035 15539638 bool any_dark = false;
5036
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
31215594 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5037 15675956 mapscr* base_scr = screen_handles[0].scr;
5038 15675956 any_dark |= is_dark(base_scr);
5039 15675956 });
5040
5041 // Handle low drawn darkness
5042
4/4
✓ Branch 0 taken 1269419 times.
✓ Branch 1 taken 14270219 times.
✓ Branch 2 taken 1025648 times.
✓ Branch 3 taken 243771 times.
15539638 if(get_qr(qr_NEW_DARKROOM) && any_dark)
5043 {
5044
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
493776 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5045 250005 mapscr* base_scr = screen_handles[0].scr;
5046 250005 calc_darkroom_combos(base_scr, offx, offy + playing_field_offset);
5047 250005 calc_darkroom_ffcs(base_scr, 0, playing_field_offset);
5048 250005 });
5049
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
243771 if(showhero)
5050
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
243771 Hero.calc_darkroom_hero(0, -playing_field_offset);
5051
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 243771 times.
493776 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5052 250005 mapscr* base_scr = screen_handles[0].scr;
5053
2/2
✓ Branch 0 taken 245275 times.
✓ Branch 1 taken 4730 times.
250005 if (!is_dark(base_scr))
5054 {
5055 4730 offy += playing_field_offset;
5056 4730 rectfill(darkscr_bmp, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5057 4730 rectfill(darkscr_bmp_trans, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5058 4730 }
5059 250005 });
5060 243771 }
5061
5062 //Darkroom if under the subscreen
5063
6/6
✓ Branch 0 taken 1269419 times.
✓ Branch 1 taken 14270219 times.
✓ Branch 2 taken 823284 times.
✓ Branch 3 taken 446135 times.
✓ Branch 4 taken 231780 times.
✓ Branch 5 taken 591504 times.
15539638 if(get_qr(qr_NEW_DARKROOM) && get_qr(qr_NEWDARK_L6) && any_dark)
5064 {
5065
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 do_primitives(framebuf, SPLAYER_DARKROOM_UNDER);
5066
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 set_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
5067
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 231780 times.
231780 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
5068 {
5069 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
5070 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
5071 }
5072
5073 231780 color_map = &trans_table2;
5074
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 231636 times.
231780 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
5075 {
5076
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 draw_trans_sprite(framebuf, darkscr_bmp, 0, 0);
5077
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 if(get_qr(qr_NEWDARK_TRANS_STACKING))
5078
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5079 144 }
5080 else
5081 {
5082
1/2
✓ Branch 0 taken 231636 times.
✗ Branch 1 not taken.
231636 masked_blit(darkscr_bmp, framebuf, 0, 0, 0, 0, framebuf->w, framebuf->h);
5083
1/2
✓ Branch 0 taken 231636 times.
✗ Branch 1 not taken.
231636 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5084 }
5085 231780 color_map = &trans_table;
5086
5087
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 set_clip_rect(framebuf, 0, 0, framebuf->w, framebuf->h);
5088
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 do_primitives(framebuf, SPLAYER_DARKROOM_OVER);
5089 231780 }
5090
5091
3/6
✓ Branch 0 taken 45626 times.
✓ Branch 1 taken 15494012 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45626 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
15539638 if (is_extended_height_mode() && lensclk && !FFCore.system_suspend[susptLENS])
5092 {
5093 draw_lens_over();
5094 --lensclk;
5095 }
5096
5097 // Draw some text on framebuf
5098
5099
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 set_clip_rect(framebuf,0,0,256,232);
5100
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 if(!get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
5101
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 draw_msgstr(6);
5102
5103 // Draw the subscreen, without clipping
5104
2/2
✓ Branch 0 taken 6288254 times.
✓ Branch 1 taken 9251384 times.
15539638 if(get_qr(qr_SUBSCREENOVERSPRITES))
5105 {
5106
2/4
✓ Branch 0 taken 6288254 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6288254 times.
✗ Branch 3 not taken.
6288254 put_passive_subscr(framebuf, 0, 0, game->should_show_time(), sspUP);
5107
5108 // Draw primitives over subscren
5109
1/2
✓ Branch 0 taken 6288254 times.
✗ Branch 1 not taken.
6288254 do_primitives(framebuf, 7); //Layer '7' appears above subscreen if quest rule is set
5110 6288254 }
5111
5112
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15539638 times.
15539638 if(get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
5113 draw_msgstr(6);
5114
5115 // Handle high-drawn darkness
5116
6/6
✓ Branch 0 taken 1269419 times.
✓ Branch 1 taken 14270219 times.
✓ Branch 2 taken 446135 times.
✓ Branch 3 taken 823284 times.
✓ Branch 4 taken 11991 times.
✓ Branch 5 taken 434144 times.
15539638 if(get_qr(qr_NEW_DARKROOM) && !get_qr(qr_NEWDARK_L6) && any_dark)
5117 {
5118
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 do_primitives(framebuf, SPLAYER_DARKROOM_UNDER);
5119
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 set_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
5120
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11991 times.
11991 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
5121 {
5122 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
5123 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
5124 }
5125
5126 11991 color_map = &trans_table2;
5127
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11991 times.
11991 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
5128 {
5129 draw_trans_sprite(framebuf, darkscr_bmp, 0, 0);
5130 if(get_qr(qr_NEWDARK_TRANS_STACKING))
5131 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5132 }
5133 else
5134 {
5135
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 masked_blit(darkscr_bmp, framebuf, 0, 0, 0, 0, framebuf->w, framebuf->h);
5136
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5137 }
5138 11991 color_map = &trans_table;
5139
5140
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 set_clip_rect(framebuf, 0, 0, framebuf->w, framebuf->h);
5141
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 do_primitives(framebuf, SPLAYER_DARKROOM_OVER);
5142 11991 }
5143
5144
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 _do_current_ffc_layer(framebuf, 7);
5145
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 draw_msgstr(7);
5146
5147
1/2
✓ Branch 0 taken 15539638 times.
✗ Branch 1 not taken.
15539638 set_clip_rect(scrollbuf, 0, 0, scrollbuf->w, scrollbuf->h);
5148
3/4
✓ Branch 0 taken 14938098 times.
✓ Branch 1 taken 601540 times.
✓ Branch 2 taken 14938098 times.
✗ Branch 3 not taken.
15539638 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_POST_DRAW);
5149 76697678 }
5150
5151 // TODO: separate setting door data and drawing door
5152 28153 void put_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t type, bool redraw, bool even_walls)
5153 {
5154
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28153 times.
28153 if (type > 8) return;
5155
5156 28153 int32_t d=scr->door_combo_set;
5157
5158
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15611 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12542 times.
28153 switch(type)
5159 {
5160 case dt_wall:
5161 case dt_walk:
5162 if(!even_walls)
5163 break;
5164 [[fallthrough]];
5165 case dt_pass:
5166
3/4
✓ Branch 0 taken 1036 times.
✓ Branch 1 taken 11506 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1036 times.
12542 if(!get_qr(qr_REPLACEOPENDOORS) && !even_walls)
5167 1036 break;
5168 [[fallthrough]];
5169 case dt_lock:
5170 case dt_shut:
5171 case dt_boss:
5172 case dt_olck:
5173 case dt_osht:
5174 case dt_obos:
5175 case dt_bomb:
5176
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 7259 times.
✓ Branch 2 taken 6784 times.
✓ Branch 3 taken 6362 times.
✓ Branch 4 taken 6712 times.
27117 switch(side)
5177 {
5178 case up:
5179 7259 scr->data[pos] = DoorComboSets[d].doorcombo_u[type][0];
5180 7259 scr->cset[pos] = DoorComboSets[d].doorcset_u[type][0];
5181 7259 scr->sflag[pos] = 0;
5182 7259 scr->data[pos+1] = DoorComboSets[d].doorcombo_u[type][1];
5183 7259 scr->cset[pos+1] = DoorComboSets[d].doorcset_u[type][1];
5184 7259 scr->sflag[pos+1] = 0;
5185 7259 scr->data[pos+16] = DoorComboSets[d].doorcombo_u[type][2];
5186 7259 scr->cset[pos+16] = DoorComboSets[d].doorcset_u[type][2];
5187 7259 scr->sflag[pos+16] = 0;
5188 7259 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_u[type][3];
5189 7259 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_u[type][3];
5190 7259 scr->sflag[pos+16+1] = 0;
5191
5192
2/2
✓ Branch 0 taken 5435 times.
✓ Branch 1 taken 1824 times.
7259 if(redraw)
5193 {
5194 3648 putcombo(dest,(pos&15)<<4,pos&0xF0,
5195 1824 DoorComboSets[d].doorcombo_u[type][0],
5196 1824 DoorComboSets[d].doorcset_u[type][0]);
5197 3648 putcombo(dest,((pos&15)<<4)+16,pos&0xF0,
5198 1824 DoorComboSets[d].doorcombo_u[type][1],
5199 1824 DoorComboSets[d].doorcset_u[type][1]);
5200 1824 }
5201
5202 7259 break;
5203
5204 case down:
5205 6784 scr->data[pos] = DoorComboSets[d].doorcombo_d[type][0];
5206 6784 scr->cset[pos] = DoorComboSets[d].doorcset_d[type][0];
5207 6784 scr->sflag[pos] = 0;
5208 6784 scr->data[pos+1] = DoorComboSets[d].doorcombo_d[type][1];
5209 6784 scr->cset[pos+1] = DoorComboSets[d].doorcset_d[type][1];
5210 6784 scr->sflag[pos+1] = 0;
5211 6784 scr->data[pos+16] = DoorComboSets[d].doorcombo_d[type][2];
5212 6784 scr->cset[pos+16] = DoorComboSets[d].doorcset_d[type][2];
5213 6784 scr->sflag[pos+16] = 0;
5214 6784 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_d[type][3];
5215 6784 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_d[type][3];
5216 6784 scr->sflag[pos+16+1] = 0;
5217
5218
2/2
✓ Branch 0 taken 5463 times.
✓ Branch 1 taken 1321 times.
6784 if(redraw)
5219 {
5220 2642 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5221 1321 DoorComboSets[d].doorcombo_d[type][2],
5222 1321 DoorComboSets[d].doorcset_d[type][2]);
5223 2642 putcombo(dest,((pos&15)<<4)+16,(pos&0xF0)+16,
5224 1321 DoorComboSets[d].doorcombo_d[type][3],
5225 1321 DoorComboSets[d].doorcset_d[type][3]);
5226 1321 }
5227
5228 6784 break;
5229
5230 case left:
5231 6362 scr->data[pos] = DoorComboSets[d].doorcombo_l[type][0];
5232 6362 scr->cset[pos] = DoorComboSets[d].doorcset_l[type][0];
5233 6362 scr->sflag[pos] = 0;
5234 6362 scr->data[pos+1] = DoorComboSets[d].doorcombo_l[type][1];
5235 6362 scr->cset[pos+1] = DoorComboSets[d].doorcset_l[type][1];
5236 6362 scr->sflag[pos+1] = 0;
5237 6362 scr->data[pos+16] = DoorComboSets[d].doorcombo_l[type][2];
5238 6362 scr->cset[pos+16] = DoorComboSets[d].doorcset_l[type][2];
5239 6362 scr->sflag[pos+16] = 0;
5240 6362 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_l[type][3];
5241 6362 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_l[type][3];
5242 6362 scr->sflag[pos+16+1] = 0;
5243 6362 scr->data[pos+32] = DoorComboSets[d].doorcombo_l[type][4];
5244 6362 scr->cset[pos+32] = DoorComboSets[d].doorcset_l[type][4];
5245 6362 scr->sflag[pos+32] = 0;
5246 6362 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_l[type][5];
5247 6362 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_l[type][5];
5248 6362 scr->sflag[pos+32+1] = 0;
5249
5250
2/2
✓ Branch 0 taken 4873 times.
✓ Branch 1 taken 1489 times.
6362 if(redraw)
5251 {
5252 2978 putcombo(dest,(pos&15)<<4,pos&0xF0,
5253 1489 DoorComboSets[d].doorcombo_l[type][0],
5254 1489 DoorComboSets[d].doorcset_l[type][0]);
5255 2978 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5256 1489 DoorComboSets[d].doorcombo_l[type][2],
5257 1489 DoorComboSets[d].doorcset_l[type][2]);
5258 2978 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5259 1489 DoorComboSets[d].doorcombo_l[type][4],
5260 1489 DoorComboSets[d].doorcset_l[type][4]);
5261 1489 }
5262
5263 6362 break;
5264
5265 case right:
5266 6712 scr->data[pos] = DoorComboSets[d].doorcombo_r[type][0];
5267 6712 scr->cset[pos] = DoorComboSets[d].doorcset_r[type][0];
5268 6712 scr->sflag[pos] = 0;
5269 6712 scr->data[pos+1] = DoorComboSets[d].doorcombo_r[type][1];
5270 6712 scr->cset[pos+1] = DoorComboSets[d].doorcset_r[type][1];
5271 6712 scr->sflag[pos+1] = 0;
5272 6712 scr->data[pos+16] = DoorComboSets[d].doorcombo_r[type][2];
5273 6712 scr->cset[pos+16] = DoorComboSets[d].doorcset_r[type][2];
5274 6712 scr->sflag[pos+16] = 0;
5275 6712 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_r[type][3];
5276 6712 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_r[type][3];
5277 6712 scr->sflag[pos+16+1] = 0;
5278 6712 scr->data[pos+32] = DoorComboSets[d].doorcombo_r[type][4];
5279 6712 scr->cset[pos+32] = DoorComboSets[d].doorcset_r[type][4];
5280 6712 scr->sflag[pos+32] = 0;
5281 6712 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_r[type][5];
5282 6712 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_r[type][5];
5283 6712 scr->sflag[pos+32+1] = 0;
5284
5285
2/2
✓ Branch 0 taken 5058 times.
✓ Branch 1 taken 1654 times.
6712 if(redraw)
5286 {
5287 3308 putcombo(dest,(pos&15)<<4,pos&0xF0,
5288 1654 DoorComboSets[d].doorcombo_r[type][0],
5289 1654 DoorComboSets[d].doorcset_r[type][0]);
5290 3308 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5291 1654 DoorComboSets[d].doorcombo_r[type][2],
5292 1654 DoorComboSets[d].doorcset_r[type][2]);
5293 3308 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5294 1654 DoorComboSets[d].doorcombo_r[type][4],
5295 1654 DoorComboSets[d].doorcset_r[type][4]);
5296 1654 }
5297
5298 6712 break;
5299 }
5300
5301 27117 break;
5302
5303 default:
5304 break;
5305 }
5306 28153 }
5307
5308 706556 static void over_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t offx, int32_t offy)
5309 {
5310 706556 int32_t door_combo_set = scr->door_combo_set;
5311 706556 int32_t x = (pos&15)<<4;
5312 706556 int32_t y = (pos&0xF0);
5313 706556 int32_t d = door_combo_set;
5314 706556 x += offx;
5315 706556 y += offy;
5316
5317
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 161136 times.
✓ Branch 2 taken 179643 times.
✓ Branch 3 taken 196353 times.
✓ Branch 4 taken 169424 times.
706556 switch(side)
5318 {
5319 case up:
5320 322272 overcombo2(dest,x,y,
5321 161136 DoorComboSets[d].bombdoorcombo_u[0],
5322 161136 DoorComboSets[d].bombdoorcset_u[0]);
5323 322272 overcombo2(dest,x+16,y,
5324 161136 DoorComboSets[d].bombdoorcombo_u[1],
5325 161136 DoorComboSets[d].bombdoorcset_u[1]);
5326 161136 break;
5327
5328 case down:
5329 359286 overcombo2(dest,x,y,
5330 179643 DoorComboSets[d].bombdoorcombo_d[0],
5331 179643 DoorComboSets[d].bombdoorcset_d[0]);
5332 359286 overcombo2(dest,x+16,y,
5333 179643 DoorComboSets[d].bombdoorcombo_d[1],
5334 179643 DoorComboSets[d].bombdoorcset_d[1]);
5335 179643 break;
5336
5337 case left:
5338 392706 overcombo2(dest,x,y,
5339 196353 DoorComboSets[d].bombdoorcombo_l[0],
5340 196353 DoorComboSets[d].bombdoorcset_l[0]);
5341 392706 overcombo2(dest,x,y+16,
5342 196353 DoorComboSets[d].bombdoorcombo_l[1],
5343 196353 DoorComboSets[d].bombdoorcset_l[1]);
5344 392706 overcombo2(dest,x,y+16,
5345 196353 DoorComboSets[d].bombdoorcombo_l[2],
5346 196353 DoorComboSets[d].bombdoorcset_l[2]);
5347 196353 break;
5348
5349 case right:
5350 338848 overcombo2(dest,x,y,
5351 169424 DoorComboSets[d].bombdoorcombo_r[0],
5352 169424 DoorComboSets[d].bombdoorcset_r[0]);
5353 338848 overcombo2(dest,x,y+16,
5354 169424 DoorComboSets[d].bombdoorcombo_r[1],
5355 169424 DoorComboSets[d].bombdoorcset_r[1]);
5356 338848 overcombo2(dest,x,y+16,
5357 169424 DoorComboSets[d].bombdoorcombo_r[2],
5358 169424 DoorComboSets[d].bombdoorcset_r[2]);
5359 169424 break;
5360 }
5361 706556 }
5362
5363 47568 void update_door(mapscr* scr, int32_t side, int32_t door, bool even_walls)
5364 {
5365
7/8
✓ Branch 0 taken 47460 times.
✓ Branch 1 taken 108 times.
✓ Branch 2 taken 47460 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22925 times.
✓ Branch 5 taken 24535 times.
✓ Branch 6 taken 530 times.
✓ Branch 7 taken 22395 times.
47568 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5366 25173 return;
5367
5368 int32_t doortype;
5369
5370
10/12
✓ Branch 0 taken 522 times.
✓ Branch 1 taken 655 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 12492 times.
✓ Branch 5 taken 910 times.
✓ Branch 6 taken 1553 times.
✓ Branch 7 taken 3192 times.
✓ Branch 8 taken 1694 times.
✓ Branch 9 taken 172 times.
✓ Branch 10 taken 67 times.
✓ Branch 11 taken 1138 times.
22395 switch(door)
5371 {
5372 case dWALL:
5373 doortype=dt_wall;
5374 break;
5375
5376 case dWALK:
5377 doortype=dt_walk;
5378 break;
5379
5380 case dOPEN:
5381 12492 doortype=dt_pass;
5382 12492 break;
5383
5384 case dLOCKED:
5385 910 doortype=dt_lock;
5386 910 break;
5387
5388 case dUNLOCKED:
5389 1553 doortype=dt_olck;
5390 1553 break;
5391
5392 case dSHUTTER:
5393
3/4
✓ Branch 0 taken 2783 times.
✓ Branch 1 taken 409 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2783 times.
3192 if(screenscrolling && ((HeroDir()^1)==side))
5394 {
5395 doortype=dt_osht;
5396 get_screen_state(scr->screen).open_doors = -4;
5397 break;
5398 }
5399
5400 [[fallthrough]];
5401 case d1WAYSHUTTER:
5402 3714 doortype=dt_shut;
5403 3714 break;
5404
5405 case dOPENSHUTTER:
5406 1694 doortype=dt_osht;
5407 1694 break;
5408
5409 case dBOSS:
5410 172 doortype=dt_boss;
5411 172 break;
5412
5413 case dOPENBOSS:
5414 67 doortype=dt_obos;
5415 67 break;
5416
5417 case dBOMBED:
5418 1138 doortype=dt_bomb;
5419 1138 break;
5420
5421 default:
5422 655 return;
5423 }
5424
5425
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 5629 times.
✓ Branch 2 taken 5770 times.
✓ Branch 3 taken 5111 times.
✓ Branch 4 taken 5230 times.
21740 switch(side)
5426 {
5427 case up:
5428 5629 put_door(scr,nullptr,7,side,doortype,false,even_walls);
5429 5629 break;
5430
5431 case down:
5432 5770 put_door(scr,nullptr,151,side,doortype,false,even_walls);
5433 5770 break;
5434
5435 case left:
5436 5111 put_door(scr,nullptr,64,side,doortype,false,even_walls);
5437 5111 break;
5438
5439 case right:
5440 5230 put_door(scr,nullptr,78,side,doortype,false,even_walls);
5441 5230 break;
5442 }
5443 47568 }
5444
5445 6504 void putdoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t door, bool redraw, bool even_walls)
5446 {
5447 /*
5448 #define dWALL 0 // 000 0
5449 #define dBOMB 6 // 011 0
5450 #define 8 // 100 0
5451 enum {dt_pass=0, dt_lock, dt_shut, dt_boss, dt_olck, dt_osht, dt_obos, dt_wall, dt_bomb, dt_walk, dt_max};
5452 */
5453
5454
7/8
✓ Branch 0 taken 6504 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6500 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 6417 times.
✓ Branch 5 taken 83 times.
✓ Branch 6 taken 8 times.
✓ Branch 7 taken 6409 times.
6504 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5455 91 return;
5456
5457 int32_t doortype;
5458
5459
8/12
✓ Branch 0 taken 227 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 50 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 362 times.
✓ Branch 7 taken 1530 times.
✓ Branch 8 taken 3958 times.
✓ Branch 9 taken 4 times.
✓ Branch 10 taken 51 times.
✓ Branch 11 taken 231 times.
6413 switch(door)
5460 {
5461 case dWALL:
5462 doortype=dt_wall;
5463 break;
5464
5465 case dWALK:
5466 doortype=dt_walk;
5467 break;
5468
5469 case dOPEN:
5470 50 doortype=dt_pass;
5471 50 break;
5472
5473 case dLOCKED:
5474 doortype=dt_lock;
5475 break;
5476
5477 case dUNLOCKED:
5478 362 doortype=dt_olck;
5479 362 break;
5480
5481 case dSHUTTER:
5482
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1530 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1530 if(screenscrolling && ((HeroDir()^1)==side))
5483 {
5484 doortype=dt_osht;
5485 get_screen_state(cur_screen).open_doors = -4;
5486 break;
5487 }
5488
5489 [[fallthrough]];
5490 case d1WAYSHUTTER:
5491 1757 doortype=dt_shut;
5492 1757 break;
5493
5494 case dOPENSHUTTER:
5495 3958 doortype=dt_osht;
5496 3958 break;
5497
5498 case dBOSS:
5499 4 doortype=dt_boss;
5500 4 break;
5501
5502 case dOPENBOSS:
5503 51 doortype=dt_obos;
5504 51 break;
5505
5506 case dBOMBED:
5507 231 doortype=dt_bomb;
5508 231 break;
5509
5510 default:
5511 return;
5512 }
5513
5514
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 1860 times.
✓ Branch 2 taken 1357 times.
✓ Branch 3 taken 1514 times.
✓ Branch 4 taken 1682 times.
6413 switch(side)
5515 {
5516 case up:
5517
2/2
✓ Branch 0 taken 1791 times.
✓ Branch 1 taken 69 times.
1860 switch(door)
5518 {
5519 case dBOMBED:
5520
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
138 if(redraw)
5521 {
5522 69 over_door(scr,dest,39,side,0,0);
5523 69 }
5524 [[fallthrough]];
5525 default:
5526 1860 put_door(scr,dest,7,side,doortype,redraw, even_walls);
5527 1860 break;
5528 }
5529
5530 1860 break;
5531
5532 case down:
5533
2/2
✓ Branch 0 taken 1318 times.
✓ Branch 1 taken 39 times.
1357 switch(door)
5534 {
5535 case dBOMBED:
5536
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
78 if(redraw)
5537 {
5538 39 over_door(scr,dest,135,side,0,0);
5539 39 }
5540 [[fallthrough]];
5541 default:
5542 1357 put_door(scr,dest,151,side,doortype,redraw, even_walls);
5543 1357 break;
5544 }
5545
5546 1357 break;
5547
5548 case left:
5549
2/2
✓ Branch 0 taken 1463 times.
✓ Branch 1 taken 51 times.
1514 switch(door)
5550 {
5551 case dBOMBED:
5552
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
102 if(redraw)
5553 {
5554 51 over_door(scr,dest,66,side,0,0);
5555 51 }
5556 [[fallthrough]];
5557 default:
5558 1514 put_door(scr,dest,64,side,doortype,redraw, even_walls);
5559 1514 break;
5560 }
5561
5562 1514 break;
5563
5564 case right:
5565
2/2
✓ Branch 0 taken 1610 times.
✓ Branch 1 taken 72 times.
1682 switch(door)
5566 {
5567 case dBOMBED:
5568
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
144 if(redraw)
5569 {
5570 72 over_door(scr,dest,77,side,0,0);
5571 72 }
5572 [[fallthrough]];
5573 default:
5574 1682 put_door(scr,dest,78,side,doortype,redraw, even_walls);
5575 1682 break;
5576 }
5577
5578 1682 break;
5579 }
5580 6504 }
5581
5582 586 void putcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5583 {
5584
1/2
✓ Branch 0 taken 586 times.
✗ Branch 1 not taken.
586 if(combo!=0)
5585 {
5586 586 putcombo(dest,x, y, combo, cset);
5587 586 }
5588 586 }
5589
5590 293 void overcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5591 {
5592
2/2
✓ Branch 0 taken 219 times.
✓ Branch 1 taken 74 times.
293 if(combo!=0)
5593 {
5594 219 overcombo(dest,x, y, combo, cset);
5595 219 }
5596 293 }
5597
5598 125 void showbombeddoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t offx, int32_t offy)
5599 {
5600 125 int32_t d = scr->door_combo_set;
5601
5602
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 37 times.
125 switch(side)
5603 {
5604 case up:
5605 86 putcombo_not_zero(dest,((7&15)<<4) + offx,(7&0xF0) + offy,
5606 43 DoorComboSets[d].doorcombo_u[dt_bomb][0],
5607 43 DoorComboSets[d].doorcset_u[dt_bomb][0]);
5608 86 putcombo_not_zero(dest,((8&15)<<4) + offx,(8&0xF0) + offy,
5609 43 DoorComboSets[d].doorcombo_u[dt_bomb][1],
5610 43 DoorComboSets[d].doorcset_u[dt_bomb][1]);
5611 86 putcombo_not_zero(dest,((23&15)<<4) + offx,(23&0xF0) + offy,
5612 43 DoorComboSets[d].doorcombo_u[dt_bomb][2],
5613 43 DoorComboSets[d].doorcset_u[dt_bomb][2]);
5614 86 putcombo_not_zero(dest,((24&15)<<4) + offx,(24&0xF0) + offy,
5615 43 DoorComboSets[d].doorcombo_u[dt_bomb][3],
5616 43 DoorComboSets[d].doorcset_u[dt_bomb][3]);
5617 86 overcombo_not_zero(dest,((39&15)<<4) + offx,(39&0xF0) + offy,
5618 43 DoorComboSets[d].bombdoorcombo_u[0],
5619 43 DoorComboSets[d].bombdoorcset_u[0]);
5620 86 overcombo_not_zero(dest,((40&15)<<4) + offx,(40&0xF0) + offy,
5621 43 DoorComboSets[d].bombdoorcombo_u[1],
5622 43 DoorComboSets[d].bombdoorcset_u[1]);
5623 43 break;
5624
5625 case down:
5626 78 putcombo_not_zero(dest,((151&15)<<4) + offx,(151&0xF0) + offy,
5627 39 DoorComboSets[d].doorcombo_d[dt_bomb][0],
5628 39 DoorComboSets[d].doorcset_d[dt_bomb][0]);
5629 78 putcombo_not_zero(dest,((152&15)<<4) + offx,(152&0xF0) + offy,
5630 39 DoorComboSets[d].doorcombo_d[dt_bomb][1],
5631 39 DoorComboSets[d].doorcset_d[dt_bomb][1]);
5632 78 putcombo_not_zero(dest,((167&15)<<4) + offx,(167&0xF0) + offy,
5633 39 DoorComboSets[d].doorcombo_d[dt_bomb][2],
5634 39 DoorComboSets[d].doorcset_d[dt_bomb][2]);
5635 78 putcombo_not_zero(dest,((168&15)<<4) + offx,(168&0xF0) + offy,
5636 39 DoorComboSets[d].doorcombo_d[dt_bomb][3],
5637 39 DoorComboSets[d].doorcset_d[dt_bomb][3]);
5638 78 overcombo_not_zero(dest,((135&15)<<4) + offx,(135&0xF0) + offy,
5639 39 DoorComboSets[d].bombdoorcombo_d[0],
5640 39 DoorComboSets[d].bombdoorcset_d[0]);
5641 78 overcombo_not_zero(dest,((136&15)<<4) + offx,(136&0xF0) + offy,
5642 39 DoorComboSets[d].bombdoorcombo_d[1],
5643 39 DoorComboSets[d].bombdoorcset_d[1]);
5644 39 break;
5645
5646 case left:
5647 12 putcombo_not_zero(dest,((64&15)<<4) + offx,(64&0xF0) + offy,
5648 6 DoorComboSets[d].doorcombo_l[dt_bomb][0],
5649 6 DoorComboSets[d].doorcset_l[dt_bomb][0]);
5650 12 putcombo_not_zero(dest,((65&15)<<4) + offx,(65&0xF0) + offy,
5651 6 DoorComboSets[d].doorcombo_l[dt_bomb][1],
5652 6 DoorComboSets[d].doorcset_l[dt_bomb][1]);
5653 12 putcombo_not_zero(dest,((80&15)<<4) + offx,(80&0xF0) + offy,
5654 6 DoorComboSets[d].doorcombo_l[dt_bomb][2],
5655 6 DoorComboSets[d].doorcset_l[dt_bomb][2]);
5656 12 putcombo_not_zero(dest,((81&15)<<4) + offx,(81&0xF0) + offy,
5657 6 DoorComboSets[d].doorcombo_l[dt_bomb][3],
5658 6 DoorComboSets[d].doorcset_l[dt_bomb][3]);
5659 12 putcombo_not_zero(dest,((96&15)<<4) + offx,(96&0xF0) + offy,
5660 6 DoorComboSets[d].doorcombo_l[dt_bomb][4],
5661 6 DoorComboSets[d].doorcset_l[dt_bomb][4]);
5662 12 putcombo_not_zero(dest,((97&15)<<4) + offx,(97&0xF0) + offy,
5663 6 DoorComboSets[d].doorcombo_l[dt_bomb][5],
5664 6 DoorComboSets[d].doorcset_l[dt_bomb][5]);
5665 12 overcombo_not_zero(dest,((66&15)<<4) + offx,(66&0xF0) + offy,
5666 6 DoorComboSets[d].bombdoorcombo_l[0],
5667 6 DoorComboSets[d].bombdoorcset_l[0]);
5668 12 overcombo_not_zero(dest,((82&15)<<4) + offx,(82&0xF0) + offy,
5669 6 DoorComboSets[d].bombdoorcombo_l[1],
5670 6 DoorComboSets[d].bombdoorcset_l[1]);
5671 12 overcombo_not_zero(dest,((98&15)<<4) + offx,(98&0xF0) + offy,
5672 6 DoorComboSets[d].bombdoorcombo_l[2],
5673 6 DoorComboSets[d].bombdoorcset_l[2]);
5674 6 break;
5675
5676 case right:
5677 74 putcombo_not_zero(dest,((78&15)<<4) + offx,(78&0xF0) + offy,
5678 37 DoorComboSets[d].doorcombo_r[dt_bomb][0],
5679 37 DoorComboSets[d].doorcset_r[dt_bomb][0]);
5680 74 putcombo_not_zero(dest,((79&15)<<4) + offx,(79&0xF0) + offy,
5681 37 DoorComboSets[d].doorcombo_r[dt_bomb][1],
5682 37 DoorComboSets[d].doorcset_r[dt_bomb][1]);
5683 74 putcombo_not_zero(dest,((94&15)<<4) + offx,(94&0xF0) + offy,
5684 37 DoorComboSets[d].doorcombo_r[dt_bomb][2],
5685 37 DoorComboSets[d].doorcset_r[dt_bomb][2]);
5686 74 putcombo_not_zero(dest,((95&15)<<4) + offx,(95&0xF0) + offy,
5687 37 DoorComboSets[d].doorcombo_r[dt_bomb][3],
5688 37 DoorComboSets[d].doorcset_r[dt_bomb][3]);
5689 74 putcombo_not_zero(dest,((110&15)<<4) + offx,(110&0xF0) + offy,
5690 37 DoorComboSets[d].doorcombo_r[dt_bomb][4],
5691 37 DoorComboSets[d].doorcset_r[dt_bomb][4]);
5692 74 putcombo_not_zero(dest,((111&15)<<4) + offx,(111&0xF0) + offy,
5693 37 DoorComboSets[d].doorcombo_r[dt_bomb][5],
5694 37 DoorComboSets[d].doorcset_r[dt_bomb][5]);
5695 74 overcombo_not_zero(dest,((77&15)<<4) + offx,(77&0xF0) + offy,
5696 37 DoorComboSets[d].bombdoorcombo_r[0],
5697 37 DoorComboSets[d].bombdoorcset_r[0]);
5698 74 overcombo_not_zero(dest,((93&15)<<4) + offx,(93&0xF0) + offy,
5699 37 DoorComboSets[d].bombdoorcombo_r[1],
5700 37 DoorComboSets[d].bombdoorcset_r[1]);
5701 74 overcombo_not_zero(dest,((109&15)<<4) + offx,(109&0xF0) + offy,
5702 37 DoorComboSets[d].bombdoorcombo_r[2],
5703 37 DoorComboSets[d].bombdoorcset_r[2]);
5704 37 break;
5705 }
5706 125 }
5707
5708 5357371 void openshutters(mapscr* scr)
5709 {
5710 5357371 bool opened_door = false;
5711
2/2
✓ Branch 0 taken 5357371 times.
✓ Branch 1 taken 21429484 times.
26786855 for(int32_t i=0; i<4; i++)
5712
2/2
✓ Branch 0 taken 21425526 times.
✓ Branch 1 taken 3958 times.
21433442 if(scr->door[i]==dSHUTTER)
5713 {
5714 3958 putdoor(scr, scrollbuf, i, dOPENSHUTTER);
5715 3958 scr->door[i]=dOPENSHUTTER;
5716 3958 opened_door = true;
5717 3958 }
5718
5719 5357371 auto& combo_cache = combo_caches::shutter;
5720 2020175719 for_every_combo_in_screen(create_screen_handles(scr), [&](const auto& handle) {
5721
3/4
✓ Branch 0 taken 2013207673 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 1610668 times.
✗ Branch 3 not taken.
2014818348 if (!combo_cache.minis[handle.data()].shutter)
5722 2014818341 return;
5723
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
14 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
5724 7 return trig.trigger_flags.get(TRIGFLAG_SHUTTER);
5725 });
5726 2014818348 });
5727
5728
2/2
✓ Branch 0 taken 5354640 times.
✓ Branch 1 taken 2731 times.
5357371 if(opened_door)
5729 2731 sfx(WAV_DOOR,128);
5730 5357371 }
5731
5732 15116786 void clear_darkroom_bitmaps()
5733 {
5734 15116786 clear_to_color(darkscr_bmp, game->get_darkscr_color());
5735 15116786 clear_to_color(darkscr_bmp_trans, game->get_darkscr_color());
5736 15116786 }
5737
5738 16030990 bool is_dark(const mapscr* scr)
5739 {
5740 16030990 bool dark = scr->flags&fDARK;
5741
2/2
✓ Branch 0 taken 3722 times.
✓ Branch 1 taken 16027268 times.
16030990 if (region_is_lit) return !dark;
5742 16027268 return dark;
5743 16030990 }
5744
5745 39226 bool scrolling_is_dark(const mapscr* scr)
5746 {
5747 39226 bool dark = scr->flags&fDARK;
5748
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 39224 times.
39226 if (scrolling_region_is_lit) return !dark;
5749 39224 return dark;
5750 39226 }
5751
5752 36764 bool is_any_dark()
5753 {
5754 36764 bool dark = false;
5755 74784 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
5756 38020 dark |= (bool)(is_dark(scr));
5757 38020 });
5758 36764 return dark;
5759 }
5760
5761 416 static mapscr prev_origin_scrs[7];
5762 416 static std::set<int> loadscr_ffc_script_ids_to_remove;
5763
5764 static void handle_screen_overlay(const std::vector<mapscr*>& screens)
5765 {
5766 mapscr* base_scr = screens[0];
5767 mapscr* previous_scr = &prev_origin_scrs[0];
5768
5769 for (int i = 0; i < 176; i++)
5770 {
5771 if (base_scr->data[i] == 0)
5772 {
5773 base_scr->data[i] = previous_scr->data[i];
5774 base_scr->sflag[i] = previous_scr->sflag[i];
5775 base_scr->cset[i] = previous_scr->cset[i];
5776 }
5777 }
5778
5779 for (int i = 0; i < 6; i++)
5780 {
5781 if (previous_scr->layermap[i] > 0 && base_scr->layermap[i] > 0)
5782 {
5783 int lm = (base_scr->layermap[i]-1)*MAPSCRS+base_scr->layerscreen[i];
5784 int fm = (previous_scr->layermap[i]-1)*MAPSCRS+previous_scr->layerscreen[i];
5785
5786 for (int j = 0; j < 176; j++)
5787 {
5788 if (TheMaps[lm].data[j] == 0)
5789 {
5790 TheMaps[lm].data[j] = TheMaps[fm].data[j];
5791 TheMaps[lm].sflag[j] = TheMaps[fm].sflag[j];
5792 TheMaps[lm].cset[j] = TheMaps[fm].cset[j];
5793 }
5794 }
5795 }
5796 }
5797
5798 for (int i = 1; i <= 6; i++)
5799 {
5800 mapscr* scr = screens[i];
5801 previous_scr = &prev_origin_scrs[i];
5802
5803 if (scr->layermap[i] > 0)
5804 {
5805 for (int y = 0; y < 11; y++)
5806 {
5807 for (int x = 0; x < 16; x++)
5808 {
5809 int c = y*16+x;
5810
5811 if (scr->data[c]==0)
5812 {
5813 scr->data[c] = previous_scr->data[c];
5814 scr->sflag[c] = previous_scr->sflag[c];
5815 scr->cset[c] = previous_scr->cset[c];
5816 }
5817 }
5818 }
5819 }
5820 }
5821 }
5822
5823 37104 static void load_a_screen_and_layers_init(int dmap, int screen, int ldir, bool screen_overlay, bool ffc_overlay)
5824 {
5825 37104 std::vector<mapscr*> screens;
5826
5827
1/2
✓ Branch 0 taken 37104 times.
✗ Branch 1 not taken.
37104 const mapscr* source = get_canonical_scr(cur_map, screen);
5828
2/4
✓ Branch 0 taken 37104 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 37104 times.
✗ Branch 3 not taken.
37104 mapscr* base_scr = new mapscr(*source);
5829 37104 temporary_screens[screen*7] = base_scr;
5830
1/2
✓ Branch 0 taken 37104 times.
✗ Branch 1 not taken.
37104 screens.push_back(base_scr);
5831
5832 37104 base_scr->valid |= mVALID; // layer 0 is always valid
5833
5834
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 35860 times.
37104 if (screen == cur_screen)
5835 35860 origin_scr = base_scr;
5836
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 35860 times.
37104 if (screen == hero_screen)
5837 35860 hero_scr = prev_hero_scr = base_scr;
5838
5839
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 36985 times.
37104 if (source->script > 0)
5840
1/2
✓ Branch 0 taken 119 times.
✗ Branch 1 not taken.
119 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
5841
5842
2/2
✓ Branch 0 taken 37104 times.
✓ Branch 1 taken 222624 times.
259728 for (int i = 0; i < 6; i++)
5843 {
5844
2/2
✓ Branch 0 taken 173538 times.
✓ Branch 1 taken 49086 times.
222624 if(source->layermap[i]>0)
5845 {
5846
3/6
✓ Branch 0 taken 49086 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 49086 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 49086 times.
✗ Branch 5 not taken.
49086 mapscr* layer_scr = new mapscr(*get_canonical_scr(source->layermap[i]-1, source->layerscreen[i]));
5847 49086 layer_scr->map = cur_map;
5848 49086 layer_scr->screen = screen;
5849
1/2
✓ Branch 0 taken 49086 times.
✗ Branch 1 not taken.
49086 screens.push_back(layer_scr);
5850 49086 }
5851 else
5852 {
5853
1/2
✓ Branch 0 taken 173538 times.
✗ Branch 1 not taken.
173538 mapscr* layer_scr = new mapscr();
5854 173538 layer_scr->map = cur_map;
5855 173538 layer_scr->screen = screen;
5856
1/2
✓ Branch 0 taken 173538 times.
✗ Branch 1 not taken.
173538 screens.push_back(layer_scr);
5857 }
5858 222624 temporary_screens[screen*7+i+1] = screens[i+1];
5859 222624 }
5860
5861
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37104 times.
37104 if (screen_overlay)
5862 handle_screen_overlay(screens);
5863
5864
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 36960 times.
37104 if (ffc_overlay)
5865 {
5866 144 mapscr* previous_scr = &prev_origin_scrs[0];
5867
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 int num_ffcs = previous_scr->numFFC();
5868
2/2
✓ Branch 0 taken 4608 times.
✓ Branch 1 taken 144 times.
4752 for (int i = 0; i < num_ffcs; i++)
5869 {
5870
2/2
✓ Branch 0 taken 4334 times.
✓ Branch 1 taken 274 times.
4608 if ((previous_scr->ffcs[i].flags&ffc_carryover))
5871 {
5872
2/4
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 274 times.
✗ Branch 3 not taken.
274 auto& ffc = base_scr->getFFC(i) = previous_scr->ffcs[i];
5873 274 ffc.screen_spawned = screen;
5874
5875
1/2
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
274 ffc_id_t ffc_id = get_region_screen_offset(screen)*MAXFFCS + i;
5876
1/2
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
274 loadscr_ffc_script_ids_to_remove.erase(ffc_id);
5877
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 274 times.
274 if (previous_scr->ffcs[i].flags&ffc_scriptreset)
5878 {
5879 FFCore.reset_script_engine_data(ScriptType::FFC, ffc_id);
5880 }
5881 274 }
5882 4608 }
5883 144 }
5884
5885
1/2
✓ Branch 0 taken 37104 times.
✗ Branch 1 not taken.
1142145 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
5886
1/2
✓ Branch 0 taken 37104 times.
✗ Branch 1 not taken.
37104 int num_ffcs = base_scr->numFFC();
5887
2/2
✓ Branch 0 taken 1105041 times.
✓ Branch 1 taken 37104 times.
1142145 for (word i = 0; i < num_ffcs; i++)
5888 {
5889 1105041 base_scr->ffcs[i].screen_spawned = screen;
5890
1/2
✓ Branch 0 taken 1105041 times.
✗ Branch 1 not taken.
1105041 base_scr->ffcs[i].x += offx;
5891
1/2
✓ Branch 0 taken 1105041 times.
✗ Branch 1 not taken.
1105041 base_scr->ffcs[i].y += offy;
5892 1105041 }
5893 37104 }
5894
5895 37104 static void load_a_screen_and_layers_post(int dmap, int screen, int ldir)
5896 {
5897 37104 mapscr* base_scr = get_scr(screen);
5898 37104 int mi = mapind(cur_map, screen);
5899
5900 // Apply perm secrets, if applicable.
5901
2/2
✓ Branch 0 taken 11520 times.
✓ Branch 1 taken 25584 times.
37104 if (canPermSecret(dmap, screen))
5902 {
5903
2/2
✓ Branch 0 taken 23059 times.
✓ Branch 1 taken 2525 times.
25584 if(game->maps[mi] & mSECRET) // if special stuff done before
5904 {
5905 2525 reveal_hidden_stairs(base_scr, screen, false);
5906 2525 trigger_secrets_for_screen(TriggerSource::SecretsScreenState, base_scr, false);
5907 2525 }
5908
2/2
✓ Branch 0 taken 25581 times.
✓ Branch 1 taken 3 times.
25584 if(game->maps[mi] & mLIGHTBEAM) // if special stuff done before
5909 {
5910
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 3 times.
24 for (int layer = 0; layer <= 6; layer++)
5911 {
5912 21 mapscr* layer_scr = get_scr_layer(screen, layer);
5913
2/2
✓ Branch 0 taken 3696 times.
✓ Branch 1 taken 21 times.
3717 for (int pos = 0; pos < 176; pos++)
5914 {
5915 3696 newcombo const* cmb = &combobuf[layer_scr->data[pos]];
5916
2/2
✓ Branch 0 taken 3693 times.
✓ Branch 1 taken 3 times.
3696 if(cmb->type == cLIGHTTARGET)
5917 {
5918
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!(cmb->usrflags&cflag1)) //Unlit version
5919 {
5920 3 layer_scr->data[pos] += 1;
5921 3 }
5922 3 }
5923 3696 }
5924 21 }
5925 3 }
5926 25584 }
5927
5928 37104 auto screen_handles = create_screen_handles(base_scr);
5929
5930 37104 int destlvl = DMaps[dmap].level;
5931 37104 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
5932 37104 toggle_gswitches_load(screen_handles);
5933
5934 37104 bool should_check_for_state_things = (screen < 0x80);
5935
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 36197 times.
37104 if (should_check_for_state_things)
5936 {
5937
2/2
✓ Branch 0 taken 35825 times.
✓ Branch 1 taken 372 times.
36197 if (game->maps[mi]&mLOCKBLOCK)
5938 372 remove_lockblocks(screen_handles);
5939
2/2
✓ Branch 0 taken 36139 times.
✓ Branch 1 taken 58 times.
36197 if (game->maps[mi]&mBOSSLOCKBLOCK)
5940 58 remove_bosslockblocks(screen_handles);
5941
2/2
✓ Branch 0 taken 36041 times.
✓ Branch 1 taken 156 times.
36197 if (game->maps[mi]&mCHEST)
5942 156 remove_chests(screen_handles);
5943
1/2
✓ Branch 0 taken 36197 times.
✗ Branch 1 not taken.
36197 if (game->maps[mi]&mLOCKEDCHEST)
5944 remove_lockedchests(screen_handles);
5945
2/2
✓ Branch 0 taken 36186 times.
✓ Branch 1 taken 11 times.
36197 if (game->maps[mi]&mBOSSCHEST)
5946 11 remove_bosschests(screen_handles);
5947
5948 36197 clear_xdoors_mi(screen_handles, mi, true);
5949 36197 clear_xstatecombos_mi(screen_handles, mi, true);
5950 36197 }
5951
5952 // check doors
5953
2/2
✓ Branch 0 taken 25583 times.
✓ Branch 1 taken 11521 times.
37104 if (isdungeon(dmap, screen))
5954 {
5955
2/2
✓ Branch 0 taken 46084 times.
✓ Branch 1 taken 11521 times.
57605 for(int32_t i=0; i<4; i++)
5956 {
5957 46084 int32_t door=base_scr->door[i];
5958
5959
5/5
✓ Branch 0 taken 5303 times.
✓ Branch 1 taken 36475 times.
✓ Branch 2 taken 2372 times.
✓ Branch 3 taken 230 times.
✓ Branch 4 taken 1704 times.
46084 switch(door)
5960 {
5961 case d1WAYSHUTTER:
5962 case dSHUTTER:
5963
3/4
✓ Branch 0 taken 1694 times.
✓ Branch 1 taken 3609 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1694 times.
5303 if ((ldir^1)==i && screen == hero_screen)
5964 {
5965 1694 base_scr->door[i]=dOPENSHUTTER;
5966 1694 }
5967
5968 5303 get_screen_state(screen).open_doors = -4;
5969 5303 break;
5970
5971 case dLOCKED:
5972
3/4
✓ Branch 0 taken 2372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1473 times.
✓ Branch 3 taken 899 times.
2372 if(should_check_for_state_things && game->maps[mi]&(1<<i))
5973 {
5974 1473 base_scr->door[i]=dUNLOCKED;
5975 1473 }
5976
5977 2372 break;
5978
5979 case dBOSS:
5980
3/4
✓ Branch 0 taken 230 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 62 times.
✓ Branch 3 taken 168 times.
230 if(should_check_for_state_things && game->maps[mi]&(1<<i))
5981 {
5982 62 base_scr->door[i]=dOPENBOSS;
5983 62 }
5984
5985 230 break;
5986
5987 case dBOMB:
5988
3/4
✓ Branch 0 taken 1704 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1087 times.
✓ Branch 3 taken 617 times.
1704 if(should_check_for_state_things && game->maps[mi]&(1<<i))
5989 {
5990 1087 base_scr->door[i]=dBOMBED;
5991 1087 }
5992
5993 1704 break;
5994 }
5995
5996 46084 update_door(base_scr, i, base_scr->door[i]);
5997
5998
4/4
✓ Branch 0 taken 41517 times.
✓ Branch 1 taken 4567 times.
✓ Branch 2 taken 736 times.
✓ Branch 3 taken 40781 times.
46084 if(door==dSHUTTER||door==d1WAYSHUTTER)
5999 {
6000 5303 base_scr->door[i]=door;
6001 5303 }
6002 46084 }
6003 11521 }
6004
6005
2/2
✓ Branch 0 taken 137 times.
✓ Branch 1 taken 36967 times.
37104 if (!(base_scr->flags3 & fCYCLEONINIT))
6006 36967 return;
6007
6008
2/2
✓ Branch 0 taken 137 times.
✓ Branch 1 taken 959 times.
1096 for (int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6009 {
6010
4/4
✓ Branch 0 taken 822 times.
✓ Branch 1 taken 137 times.
✓ Branch 2 taken 377 times.
✓ Branch 3 taken 445 times.
959 if (j<0 || base_scr->layermap[j] > 0)
6011 {
6012 514 mapscr* layer_scr = get_scr_layer(screen, j + 1);
6013
3/4
✓ Branch 0 taken 377 times.
✓ Branch 1 taken 137 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 377 times.
514 mapscr* layerscreen= (j<0 ? base_scr : layer_scr->valid ? layer_scr :
6014 &TheMaps[(base_scr->layermap[j]-1)*MAPSCRS]+base_scr->layerscreen[j]);
6015
6016
2/2
✓ Branch 0 taken 90464 times.
✓ Branch 1 taken 514 times.
90978 for(int32_t i=0; i<176; ++i)
6017 {
6018 90464 int32_t c=layerscreen->data[i];
6019
6020 // New screen flag: Cycle Combos At Screen Init
6021
5/6
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 90399 times.
✓ Branch 2 taken 29 times.
✓ Branch 3 taken 36 times.
✓ Branch 4 taken 29 times.
✗ Branch 5 not taken.
90464 if(combobuf[c].nextcombo != 0 && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6022 {
6023 65 int32_t r = 0;
6024
6025
4/4
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 65 times.
149 while(combobuf[c].can_cycle() && r++ < 10)
6026 {
6027 84 newcombo const& cmb = combobuf[c];
6028 84 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6029
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6030 84 layerscreen->data[i] = cid;
6031
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 69 times.
84 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6032
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6033 84 c = layerscreen->data[i];
6034 }
6035 65 }
6036 90464 }
6037 514 }
6038 959 }
6039 37104 }
6040
6041 // Set `cur_screen` to `screen` and load new screens into temporary memory.
6042 //
6043 // Called anytime a player moves to a new screen (either via warping, scrolling, continue, starting
6044 // the game, etc...)
6045 //
6046 // Note: for regions, only the initial screen load calls this function. Simply walking between
6047 // screens in the same region does not use this, because every screen in a region is loaded into
6048 // temporary memory up front.
6049 //
6050 // If scr >= 0x80, `hero_screen` will be saved to `home_screen` and also be loaded into
6051 // `special_warp_return_scr`.
6052 //
6053 // If origin_screen_overlay is true, the old origin_scr combos will be copied to the new origin_scr combos
6054 // on all layers (but only where the new screen has a 0 combo).
6055 //
6056 // TODO: loadscr should set curdmap, but currently callers do that.
6057 35860 void loadscr(int32_t destdmap, int32_t screen, int32_t ldir, bool origin_screen_overlay, bool no_x80_dir)
6058 {
6059 35860 zapp_reporting_set_tag("screen", screen);
6060
2/2
✓ Branch 0 taken 8934 times.
✓ Branch 1 taken 26926 times.
35860 if (destdmap != -1)
6061 8934 zapp_reporting_set_tag("dmap", destdmap);
6062
6063 35860 int32_t orig_destdmap = destdmap;
6064
2/2
✓ Branch 0 taken 8934 times.
✓ Branch 1 taken 26926 times.
35860 if (destdmap < 0) destdmap = cur_dmap;
6065
6066
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35860 times.
35860 if (replay_is_active())
6067 {
6068
1/2
✓ Branch 0 taken 35860 times.
✗ Branch 1 not taken.
35860 if (replay_get_mode() == ReplayMode::ManualTakeover)
6069 replay_stop_manual_takeover();
6070
6071
2/2
✓ Branch 0 taken 26926 times.
✓ Branch 1 taken 8934 times.
35860 if (orig_destdmap != -1)
6072 {
6073
2/2
✓ Branch 0 taken 7860 times.
✓ Branch 1 taken 1074 times.
8934 if (strlen(DMaps[orig_destdmap].name) > 0)
6074 {
6075
1/2
✓ Branch 0 taken 7860 times.
✗ Branch 1 not taken.
7860 replay_step_comment(fmt::format("dmap={} {}", orig_destdmap, DMaps[orig_destdmap].name));
6076 7860 }
6077 else
6078 {
6079
1/2
✓ Branch 0 taken 1074 times.
✗ Branch 1 not taken.
1074 replay_step_comment(fmt::format("dmap={}", orig_destdmap));
6080 }
6081 8934 }
6082 35860 replay_step_comment_loadscr(screen);
6083
6084 // Reset the rngs and frame count so that recording steps can be modified without impacting
6085 // behavior of later screens.
6086 35860 replay_sync_rng();
6087 35860 }
6088
6089
2/2
✓ Branch 0 taken 1707536 times.
✓ Branch 1 taken 35860 times.
1743396 for (auto& state : get_screen_states())
6090 1707536 state.second.triggered_secrets = false;
6091 35860 slopes.clear();
6092 35860 Hero.clear_platform_ffc();
6093 35860 timeExitAllGenscript(GENSCR_ST_CHANGE_SCREEN);
6094 35860 clear_darkroom_bitmaps();
6095 35860 msgscr = nullptr;
6096
6097
2/2
✓ Branch 0 taken 50398165 times.
✓ Branch 1 taken 35860 times.
50434025 for (word x=0; x<animated_combos; x++)
6098 {
6099
2/2
✓ Branch 0 taken 20920186 times.
✓ Branch 1 taken 29477979 times.
50398165 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6100 {
6101 20920186 combobuf[animated_combo_table4[x][0]].aclk = 0;
6102 20920186 }
6103 50398165 }
6104 35860 reset_combo_animations2();
6105 35860 region_is_lit = false;
6106
6107 // Legacy features (combo and ffc overlays) may need the previous origin screens during loading
6108 // of the new ones.
6109 35860 bool origin_ffc_overlay = false;
6110
2/2
✓ Branch 0 taken 34717 times.
✓ Branch 1 taken 1143 times.
35860 if (origin_scr)
6111 {
6112
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 34715 times.
34717 if (!(origin_scr->flags5&fNOFFCARRYOVER))
6113 {
6114 34715 int c = origin_scr->numFFC();
6115
2/2
✓ Branch 0 taken 34571 times.
✓ Branch 1 taken 1038879 times.
1073450 for (int i = 0; i < c; i++)
6116 {
6117
2/2
✓ Branch 0 taken 1038735 times.
✓ Branch 1 taken 144 times.
1038879 if (origin_scr->ffcs[i].flags&ffc_carryover)
6118 {
6119 144 origin_ffc_overlay = true;
6120 144 break;
6121 }
6122 1038735 }
6123 34715 }
6124
6125
3/4
✓ Branch 0 taken 34717 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 144 times.
✓ Branch 3 taken 34573 times.
34717 if (origin_screen_overlay || origin_ffc_overlay)
6126 {
6127
2/2
✓ Branch 0 taken 1008 times.
✓ Branch 1 taken 144 times.
1152 for (int i = 0; i <= 6; i++)
6128 {
6129 1008 mapscr* prev_scr = get_scr_layer(cur_screen, i);
6130
1/2
✓ Branch 0 taken 1008 times.
✗ Branch 1 not taken.
1008 if (prev_scr)
6131 1008 prev_origin_scrs[i] = *prev_scr;
6132 else
6133 prev_origin_scrs[i] = {};
6134 1008 }
6135 144 }
6136 34717 }
6137
6138 // Based on origin_ffc_overlay, some ffc scripts don't get reset. This set starts with all of
6139 // them, but scripts that need their data to persist will be removed.
6140 35860 loadscr_ffc_script_ids_to_remove.clear();
6141
2/2
✓ Branch 0 taken 74704391 times.
✓ Branch 1 taken 35860 times.
74740251 for (auto& key : scriptEngineDatas | std::views::keys)
6142 {
6143
2/2
✓ Branch 0 taken 73582486 times.
✓ Branch 1 taken 1121905 times.
74704391 if (key.first == ScriptType::FFC)
6144 1121905 loadscr_ffc_script_ids_to_remove.insert(key.second);
6145 }
6146
6147 35860 load_region(destdmap, screen);
6148
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 34953 times.
35860 home_screen = screen >= 0x80 ? hero_screen : cur_screen;
6149 35860 hero_screen = screen;
6150
6151 35860 cpos_clear_all();
6152 35860 FFCore.destroyScriptableObjectsOfType(ScriptType::Screen);
6153 35860 FFCore.clear_combo_scripts();
6154
6155
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 35696 times.
35860 if (is_in_scrolling_region())
6156 {
6157
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6158 {
6159
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6160 {
6161
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool screen_overlay = origin_screen_overlay && screen == cur_screen;
6162
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool ffc_overlay = origin_ffc_overlay && screen == cur_screen;
6163 1408 load_a_screen_and_layers_init(destdmap, screen, ldir, screen_overlay, ffc_overlay);
6164 1408 }
6165 20992 }
6166 164 }
6167 else
6168 {
6169 35696 load_a_screen_and_layers_init(destdmap, screen, ldir, origin_screen_overlay, origin_ffc_overlay);
6170 }
6171
6172 35860 prepare_current_region_handles();
6173
6174
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 35696 times.
35860 if (is_in_scrolling_region())
6175 {
6176
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6177 {
6178
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6179 {
6180 1408 load_a_screen_and_layers_post(destdmap, screen, ldir);
6181 1408 }
6182 20992 }
6183 164 }
6184 else
6185 {
6186 35696 load_a_screen_and_layers_post(destdmap, screen, ldir);
6187 }
6188
6189 // If on a special screen, load the screen the player is currently on (home_screen) into special_warp_return_scr.
6190
2/2
✓ Branch 0 taken 34953 times.
✓ Branch 1 taken 907 times.
35860 if (screen >= 0x80)
6191
2/2
✓ Branch 0 taken 476 times.
✓ Branch 1 taken 431 times.
907 loadscr_old(orig_destdmap, home_screen, no_x80_dir ? -1 : ldir, origin_screen_overlay);
6192
6193 35860 update_slope_comboposes();
6194 35860 cpos_force_update();
6195 35860 trig_trigger_groups();
6196
6197
2/2
✓ Branch 0 taken 1121631 times.
✓ Branch 1 taken 35860 times.
1157491 for (int index : loadscr_ffc_script_ids_to_remove)
6198 {
6199 1121631 FFCore.destroyScriptableObject(ScriptType::FFC, index);
6200 }
6201
6202 // "extended height mode" includes the top 56 pixels as part of the visible mapscr viewport,
6203 // allowing for regions to display 4 more rows of combos (as many as ALTTP does). This part of
6204 // screen is normally reserved for the passive subscreen, but in this mode mapscr combos are drawn below it.
6205 // It is up to the quest designer to make their subscreen be actually transparent.
6206 //
6207 // When not in "extended height mode" (otherwise 56 is 0):
6208 // - playing_field_offset: 56, but changes during earthquakes
6209 // - original_playing_field_offset: always 56
6210 //
6211 // These values are used to adjust where things are drawn on screen to account for the passive subscreen. Examples:
6212 // - yofs of sprites
6213 // - bitmap y offsets in draw_screen
6214 // - drawing offsets for putscr, do_layer
6215 // - drawing offsets for various calls to overtile16 (see bomb weapon explosion)
6216 // - lots more
6217 //
6218 // TODO: consider refactor of yofs, make yofs start as 0 by default and add playing_field_offset at draw time?
6219
2/2
✓ Branch 0 taken 142 times.
✓ Branch 1 taken 35718 times.
35860 if (is_extended_height_mode())
6220 {
6221 142 playing_field_offset = 0;
6222 142 original_playing_field_offset = 0;
6223 // A few sprites exist as globals, so we must manually reset them.
6224 142 Hero.yofs = 0;
6225 142 mblock2.yofs = 0;
6226 142 }
6227 else
6228 {
6229 35718 mblock2.yofs = Hero.yofs = playing_field_offset = 56;
6230 35718 original_playing_field_offset = 56;
6231 }
6232 35860 is_any_room_dark = is_any_dark();
6233
6234 35860 game->load_portal();
6235 35860 throwGenScriptEvent(GENSCR_EVENT_CHANGE_SCREEN);
6236
3/4
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 35825 times.
✓ Branch 2 taken 35 times.
✗ Branch 3 not taken.
35860 if (Hero.lift_wpn && get_qr(qr_CARRYABLE_NO_ACROSS_SCREEN))
6237 {
6238 delete Hero.lift_wpn;
6239 Hero.lift_wpn = nullptr;
6240 }
6241
6242 35860 enemy_spawning_has_checked_been_here = false;
6243 35860 markBmap(-1, hero_screen);
6244 35860 Hero.maybe_begin_advanced_maze();
6245 35860 }
6246
6247 // Don't use this directly! Use `loadscr` instead.
6248 907 void loadscr_old(int32_t destdmap, int32_t screen,int32_t ldir,bool overlay)
6249 {
6250
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 int32_t destlvl = DMaps[destdmap < 0 ? cur_dmap : destdmap].level;
6251
6252 907 mapscr previous_scr = *special_warp_return_scr;
6253 907 mapscr* scr = special_warp_return_scr;
6254
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 const mapscr* source = get_canonical_scr(cur_map, screen);
6255
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 *scr = *source;
6256
6257
2/2
✓ Branch 0 taken 5442 times.
✓ Branch 1 taken 907 times.
6349 for (int i = 1; i <= 6; i++)
6258 {
6259
2/2
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 5059 times.
5442 if (scr->layermap[i-1] > 0)
6260
2/4
✓ Branch 0 taken 383 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 383 times.
✗ Branch 3 not taken.
383 special_warp_return_scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6261 else
6262 5059 special_warp_return_scrs[i] = {};
6263 5442 }
6264
6265 907 scr->valid |= mVALID; //layer 0 is always valid
6266
6267
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 907 times.
907 if ( source->script > 0 )
6268 {
6269 scr->script = source->script;
6270 for ( int32_t q = 0; q < 8; q++ )
6271 {
6272 scr->screeninitd[q] = source->screeninitd[q];
6273 }
6274 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
6275 }
6276 else
6277 {
6278 907 scr->script = 0;
6279 }
6280
6281
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 if(overlay)
6282 {
6283 for(int32_t c=0; c< 176; ++c)
6284 {
6285 if(scr->data[c]==0)
6286 {
6287 scr->data[c]=previous_scr.data[c];
6288 scr->sflag[c]=previous_scr.sflag[c];
6289 scr->cset[c]=previous_scr.cset[c];
6290 }
6291 }
6292
6293 for(int32_t i=0; i<6; i++)
6294 {
6295 if(previous_scr.layermap[i]>0 && scr->layermap[i]>0)
6296 {
6297 int32_t lm = (scr->layermap[i]-1)*MAPSCRS+scr->layerscreen[i];
6298 int32_t fm = (previous_scr.layermap[i]-1)*MAPSCRS+previous_scr.layerscreen[i];
6299
6300 for(int32_t c=0; c< 176; ++c)
6301 {
6302 if(TheMaps[lm].data[c]==0)
6303 {
6304 TheMaps[lm].data[c] = TheMaps[fm].data[c];
6305 TheMaps[lm].sflag[c] = TheMaps[fm].sflag[c];
6306 TheMaps[lm].cset[c] = TheMaps[fm].cset[c];
6307 }
6308 }
6309 }
6310 }
6311 }
6312
6313
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
29900 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
6314
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 int c = scr->numFFC();
6315
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 28993 times.
29900 for (word i = 0; i < c; i++)
6316 {
6317 28993 scr->ffcs[i].screen_spawned = screen;
6318
1/2
✓ Branch 0 taken 28993 times.
✗ Branch 1 not taken.
28993 scr->ffcs[i].x += offx;
6319
1/2
✓ Branch 0 taken 28993 times.
✗ Branch 1 not taken.
28993 scr->ffcs[i].y += offy;
6320 28993 }
6321
6322 907 int mi = mapind(cur_map, screen);
6323
6324 // Apply perm secrets, if applicable.
6325
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✓ Branch 3 taken 371 times.
907 if(canPermSecret(destdmap,screen))
6326 {
6327
3/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 332 times.
536 if(game->maps[mi]&mSECRET) // if special stuff done before
6328 {
6329
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 reveal_hidden_stairs(scr, screen, false);
6330
6331
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
6332
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 get_screen_state(special_warp_return_scr->screen).triggered_secrets = true;
6333 204 bool do_replay_comment = true;
6334 204 bool from_active_screen = false;
6335
2/4
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✗ Branch 3 not taken.
204 trigger_secrets_for_screen_internal(create_screen_handles(special_warp_return_scr), from_active_screen, false, -1, do_replay_comment);
6336 204 }
6337
2/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✗ Branch 3 not taken.
536 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6338 {
6339 for (int layer = 0; layer <= 6; layer++)
6340 {
6341 mapscr* tscr = &special_warp_return_scrs[layer];
6342 for (int pos = 0; pos < 176; pos++)
6343 {
6344 newcombo const* cmb = &combobuf[tscr->data[pos]];
6345 if(cmb->type == cLIGHTTARGET)
6346 {
6347 if(!(cmb->usrflags&cflag1)) //Unlit version
6348 {
6349 tscr->data[pos] += 1;
6350 }
6351 }
6352 }
6353 }
6354 }
6355 536 }
6356
6357 screen_handles_t screen_handles;
6358
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 6349 times.
7256 for (int i = 0; i <= 6; i++)
6359
3/4
✓ Branch 0 taken 6349 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1289 times.
✓ Branch 3 taken 5060 times.
6349 screen_handles[i] = {scr, special_warp_return_scrs[i].is_valid() ? &special_warp_return_scrs[i] : nullptr, screen, i};
6360
6361
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 907 times.
✗ Branch 3 not taken.
907 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
6362
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 toggle_gswitches_load(screen_handles);
6363
6364
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 902 times.
907 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6365 {
6366
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 remove_lockblocks(screen_handles);
6367 5 }
6368
6369
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 906 times.
907 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6370 {
6371
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6372 1 }
6373
6374
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mCHEST) // if special stuff done before
6375 {
6376 remove_chests(screen_handles);
6377 }
6378
6379
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6380 {
6381 remove_lockedchests(screen_handles);
6382 }
6383
6384
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6385 {
6386 remove_bosschests(screen_handles);
6387 }
6388
6389
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 clear_xdoors(screen_handles, true);
6390
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 clear_xstatecombos(screen_handles, true);
6391
6392 // check doors
6393
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 371 times.
✓ Branch 3 taken 536 times.
907 if (isdungeon(destdmap, screen))
6394 {
6395
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 371 times.
1855 for(int32_t i=0; i<4; i++)
6396 {
6397 1484 int32_t door=scr->door[i];
6398
6399
4/4
✓ Branch 0 taken 91 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 89 times.
✓ Branch 3 taken 1295 times.
1484 switch(door)
6400 {
6401 case d1WAYSHUTTER:
6402 case dSHUTTER:
6403
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1295 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1295 if ((ldir^1)==i && screen == home_screen)
6404 {
6405 scr->door[i]=dOPENSHUTTER;
6406 }
6407
6408
2/2
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 1190 times.
1295 get_screen_state(screen).open_doors = -4;
6409 105 break;
6410
6411 case dLOCKED:
6412
3/4
✓ Branch 0 taken 91 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
✓ Branch 3 taken 11 times.
91 if(game->maps[mi]&(1<<i))
6413 {
6414 80 scr->door[i]=dUNLOCKED;
6415 80 }
6416
6417 91 break;
6418
6419 case dBOSS:
6420
3/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 4 times.
9 if(game->maps[mi]&(1<<i))
6421 {
6422 5 scr->door[i]=dOPENBOSS;
6423 5 }
6424
6425 9 break;
6426
6427 case dBOMB:
6428
3/4
✓ Branch 0 taken 89 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 51 times.
✓ Branch 3 taken 38 times.
89 if(game->maps[mi]&(1<<i))
6429 {
6430 51 scr->door[i]=dBOMBED;
6431 51 }
6432
6433 89 break;
6434 }
6435
6436
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 1190 times.
294 update_door(scr, i, scr->door[i]);
6437
6438
4/4
✓ Branch 0 taken 1390 times.
✓ Branch 1 taken 94 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 1379 times.
1484 if(door==dSHUTTER||door==d1WAYSHUTTER)
6439 {
6440 105 scr->door[i]=door;
6441 105 }
6442 1484 }
6443 371 }
6444
6445
2/2
✓ Branch 0 taken 6915 times.
✓ Branch 1 taken 549 times.
7256 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6446 {
6447
4/4
✓ Branch 0 taken 5442 times.
✓ Branch 1 taken 1473 times.
✓ Branch 2 taken 2763 times.
✓ Branch 3 taken 2679 times.
6915 if (j<0 || scr->layermap[j] > 0)
6448 {
6449
4/4
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 383 times.
✓ Branch 2 taken 382 times.
✓ Branch 3 taken 1 times.
4236 mapscr *layerscreen= (j<0 ? scr : special_warp_return_scrs[j+1].valid ? &special_warp_return_scrs[j+1] :
6450 1 &TheMaps[(scr->layermap[j]-1)*MAPSCRS]+scr->layerscreen[j]);
6451
6452
2/2
✓ Branch 0 taken 224660 times.
✓ Branch 1 taken 3670 times.
228330 for(int32_t i=0; i<176; ++i)
6453 {
6454 224660 int32_t c=layerscreen->data[i];
6455
6456 // New screen flag: Cycle Combos At Screen Init
6457
5/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 224654 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 2380 times.
✓ Branch 7 taken 2380 times.
224660 if(combobuf[c].nextcombo != 0 && (scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6458 {
6459 2380 int32_t r = 0;
6460
6461
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 2380 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2380 while(combobuf[c].can_cycle() && r++ < 10)
6462 {
6463 newcombo const& cmb = combobuf[c];
6464 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6465 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6466 layerscreen->data[i] = cid;
6467 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6468 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6469 c = layerscreen->data[i];
6470 }
6471 }
6472 227040 }
6473 3670 }
6474 6349 }
6475 5309 }
6476
6477 // Load screen (and layers). Unlike loadscr, this doesn't load to the global temporary_screens, but
6478 // instead returns an array of mapscr.
6479 // Used to draw/save the map.
6480 45680 std::array<mapscr, 7> loadscr2(int32_t screen)
6481 {
6482 45680 std::array<mapscr, 7> scrs;
6483 45680 mapscr* scr = &scrs[0];
6484
6485
2/2
✓ Branch 0 taken 64716181 times.
✓ Branch 1 taken 45680 times.
64761861 for(word x=0; x<animated_combos; x++)
6486 {
6487
2/2
✓ Branch 0 taken 31963685 times.
✓ Branch 1 taken 32752496 times.
64716181 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6488 {
6489 32752496 combobuf[animated_combo_table4[x][0]].aclk=0;
6490 32752496 }
6491 64716181 }
6492
6493
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 const mapscr* source = get_canonical_scr(cur_map, screen);
6494
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 if (!source->is_valid())
6495 {
6496 scrs[0].valid = 0;
6497 return scrs;
6498 }
6499
6500
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 *scr = *get_canonical_scr(cur_map, screen);
6501
2/2
✓ Branch 0 taken 274080 times.
✓ Branch 1 taken 45680 times.
319760 for (int i = 1; i <= 6; i++)
6502 {
6503
2/2
✓ Branch 0 taken 64814 times.
✓ Branch 1 taken 209266 times.
274080 if (scr->layermap[i-1] > 0)
6504
2/4
✓ Branch 0 taken 64814 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 64814 times.
✗ Branch 3 not taken.
64814 scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6505 else
6506 209266 scrs[i] = {};
6507 274080 }
6508
6509 screen_handles_t screen_handles;
6510
2/2
✓ Branch 0 taken 45680 times.
✓ Branch 1 taken 319760 times.
365440 for (int i = 0; i < 7; i++)
6511
3/4
✓ Branch 0 taken 319760 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103790 times.
✓ Branch 3 taken 215970 times.
319760 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
6512
6513 45680 int mi = mapind(cur_map, screen);
6514
6515
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45626 times.
✓ Branch 3 taken 54 times.
45680 if(canPermSecret(-1,screen))
6516 {
6517
3/4
✓ Branch 0 taken 45626 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5730 times.
✓ Branch 3 taken 39896 times.
45626 if(game->maps[mi]&mSECRET) // if special stuff done before
6518 {
6519
1/2
✓ Branch 0 taken 5730 times.
✗ Branch 1 not taken.
5730 reveal_hidden_stairs(scr, screen, false);
6520 5730 bool from_active_screen = false;
6521 5730 bool do_replay_comment = true;
6522
1/2
✓ Branch 0 taken 5730 times.
✗ Branch 1 not taken.
5730 trigger_secrets_for_screen_internal(screen_handles, from_active_screen, false, -1, do_replay_comment);
6523 5730 }
6524
3/4
✓ Branch 0 taken 45626 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45609 times.
✓ Branch 3 taken 17 times.
45626 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6525 {
6526
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 17 times.
136 for (int layer = 0; layer <= 6; layer++)
6527 {
6528 119 mapscr* tscr = &scrs[layer];
6529
2/2
✓ Branch 0 taken 20944 times.
✓ Branch 1 taken 119 times.
21063 for (int pos = 0; pos < 176; pos++)
6530 {
6531 20944 newcombo const* cmb = &combobuf[tscr->data[pos]];
6532
2/2
✓ Branch 0 taken 20927 times.
✓ Branch 1 taken 17 times.
20944 if(cmb->type == cLIGHTTARGET)
6533 {
6534
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if(!(cmb->usrflags&cflag1)) //Unlit version
6535 {
6536 17 tscr->data[pos] += 1;
6537 17 }
6538 17 }
6539 20944 }
6540 119 }
6541 17 }
6542 45626 }
6543
6544
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 233 times.
✓ Branch 3 taken 45447 times.
45680 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6545 {
6546
1/2
✓ Branch 0 taken 233 times.
✗ Branch 1 not taken.
233 remove_lockblocks(screen_handles);
6547 233 }
6548
6549
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 45679 times.
45680 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6550 {
6551
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6552 1 }
6553
6554
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 101 times.
✓ Branch 3 taken 45579 times.
45680 if(game->maps[mi]&mCHEST) // if special stuff done before
6555 {
6556
1/2
✓ Branch 0 taken 101 times.
✗ Branch 1 not taken.
101 remove_chests(screen_handles);
6557 101 }
6558
6559
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 45656 times.
45680 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6560 {
6561
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 remove_lockedchests(screen_handles);
6562 24 }
6563
6564
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 45680 times.
45680 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6565 {
6566 remove_bosschests(screen_handles);
6567 }
6568
6569
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 clear_xdoors(screen_handles);
6570
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 clear_xstatecombos(screen_handles);
6571
6572 // check doors
6573
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 54 times.
✓ Branch 3 taken 45626 times.
45680 if (isdungeon(screen))
6574 {
6575
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 54 times.
270 for(int32_t i=0; i<4; i++)
6576 {
6577 216 int32_t door=scr->door[i];
6578 216 bool putit=true;
6579
6580
4/5
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 61 times.
✓ Branch 4 taken 139 times.
216 switch(door)
6581 {
6582 case d1WAYSHUTTER:
6583 case dSHUTTER:
6584 61 break;
6585
6586 case dLOCKED:
6587
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12 if(game->maps[mi]&(1<<i))
6588 {
6589 12 scr->door[i]=dUNLOCKED;
6590 12 }
6591
6592 12 break;
6593
6594 case dBOSS:
6595
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 if(game->maps[mi]&(1<<i))
6596 {
6597 scr->door[i]=dOPENBOSS;
6598 }
6599
6600 4 break;
6601
6602 case dBOMB:
6603 if(game->maps[mi]&(1<<i))
6604 {
6605 scr->door[i]=dBOMBED;
6606 }
6607
6608 break;
6609 }
6610
6611
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
216 if(putit)
6612 {
6613
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 putdoor(scr, scrollbuf, i, scr->door[i], false);
6614 216 }
6615
6616
3/4
✓ Branch 0 taken 155 times.
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 155 times.
216 if(door==dSHUTTER||door==d1WAYSHUTTER)
6617 {
6618 61 scr->door[i]=door;
6619 61 }
6620 216 }
6621 54 }
6622
6623
2/2
✓ Branch 0 taken 319760 times.
✓ Branch 1 taken 45680 times.
365440 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6624 {
6625
4/4
✓ Branch 0 taken 274080 times.
✓ Branch 1 taken 45680 times.
✓ Branch 2 taken 64814 times.
✓ Branch 3 taken 209266 times.
319760 if (j < 0 || scr->layermap[j] > 0)
6626 {
6627
2/2
✓ Branch 0 taken 64814 times.
✓ Branch 1 taken 45680 times.
110494 mapscr *layerscreen= (j<0 ? scr
6628 64814 : &(TheMaps[(scr->layermap[j]-1)*MAPSCRS+scr->layerscreen[j]]));
6629
6630
2/2
✓ Branch 0 taken 19446944 times.
✓ Branch 1 taken 110494 times.
19557438 for(int32_t i=0; i<176; ++i)
6631 {
6632 19446944 int32_t c=layerscreen->data[i];
6633
6634 // New screen flag: Cycle Combos At Screen Init
6635
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 19446944 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
19446944 if((scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6636 {
6637 int32_t r = 0;
6638
6639 while(combobuf[c].can_cycle() && r++ < 10)
6640 {
6641 newcombo const& cmb = combobuf[c];
6642 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6643 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6644 layerscreen->data[i] = cid;
6645 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6646 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6647 c = layerscreen->data[i];
6648 }
6649 }
6650 19446944 }
6651 110494 }
6652 319760 }
6653
6654 45680 return scrs;
6655
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 }
6656
6657 19015924 void putscr(mapscr* scr, BITMAP* dest, int32_t x, int32_t y)
6658 {
6659 // This is a bogus value while screenscrolling == true, but that's ok
6660 // because it is only used to calculate the rpos, and during screenscrolling
6661 // only the modulus to get pos (draw_cmb_pos does RPOS_TO_POS) is needed, which
6662 // is always the same no matter the value of scr.
6663 19015924 int screen = get_screen_for_world_xy(x, y);
6664
6665 19015924 x -= viewport.x;
6666 19015924 y -= viewport.y;
6667
6668
3/6
✓ Branch 0 taken 19015924 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19015924 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 19015924 times.
19015924 if (!scr->is_valid()||!show_layers[0]||scr->hidelayers & 1)
6669 {
6670 rectfill(dest,x,y,x+255,y+175,0);
6671 return;
6672 }
6673
6674 37902938 bool over = XOR(scr->flags7&fLAYER2BG,DMaps[cur_dmap].flags&dmfLAYER2BG)
6675
2/2
✓ Branch 0 taken 128910 times.
✓ Branch 1 taken 18887014 times.
19015924 || XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG);
6676
6677 int start_x, end_x, start_y, end_y;
6678 19015924 get_bounds_for_draw_cmb_calls(dest, x, y, start_x, end_x, start_y, end_y);
6679
2/2
✓ Branch 0 taken 19015924 times.
✓ Branch 1 taken 202547651 times.
221563575 for (int cy = start_y; cy < end_y; cy++)
6680 {
6681
2/2
✓ Branch 0 taken 3075812610 times.
✓ Branch 1 taken 202547651 times.
3278360261 for (int cx = start_x; cx < end_x; cx++)
6682 {
6683 3075812610 int i = cx + cy*16;
6684
2/2
✓ Branch 0 taken 357850966 times.
✓ Branch 1 taken 2717961644 times.
3075812610 auto rpos = screenscrolling ? rpos_t::None : POS_TO_RPOS(i, screen);
6685 3075812610 draw_cmb_pos(dest, x + cx*16, y + cy*16, rpos, scr->data[i], scr->cset[i], 0, over, false);
6686 3075812610 }
6687 202547651 }
6688 19015924 }
6689
6690 15539638 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y)
6691 {
6692
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15539638 times.
15539638 if (!show_layers[0])
6693 {
6694 return;
6695 }
6696
6697 15539638 x -= viewport.x;
6698 15539638 y -= viewport.y;
6699
6700
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15539638 times.
31215594 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
6701 15675956 mapscr* scr = screen_handles[0].base_scr;
6702
1/2
✓ Branch 0 taken 15675956 times.
✗ Branch 1 not taken.
15675956 if (!scr->is_valid())
6703 return;
6704
6705
2/2
✓ Branch 0 taken 123411 times.
✓ Branch 1 taken 15552545 times.
15675956 if(scr->door[0]==dBOMBED)
6706 {
6707 123411 over_door(scr, dest, 39, up, offx+x, offy+y);
6708 123411 }
6709
6710
2/2
✓ Branch 0 taken 143109 times.
✓ Branch 1 taken 15532847 times.
15675956 if(scr->door[1]==dBOMBED)
6711 {
6712 143109 over_door(scr, dest, 135, down, offx+x, offy+y);
6713 143109 }
6714
6715
2/2
✓ Branch 0 taken 155862 times.
✓ Branch 1 taken 15520094 times.
15675956 if(scr->door[2]==dBOMBED)
6716 {
6717 155862 over_door(scr, dest, 66, left, offx+x, offy+y);
6718 155862 }
6719
6720
2/2
✓ Branch 0 taken 132289 times.
✓ Branch 1 taken 15543667 times.
15675956 if(scr->door[3]==dBOMBED)
6721 {
6722 132289 over_door(scr, dest, 77, right, offx+x, offy+y);
6723 132289 }
6724 15675956 });
6725 15539638 }
6726
6727 3339968 void putscrdoors(mapscr* scr, BITMAP *dest, int32_t x, int32_t y)
6728 {
6729
2/4
✓ Branch 0 taken 3339968 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3339968 times.
✗ Branch 3 not taken.
3339968 if (!scr->is_valid() || !show_layers[0])
6730 return;
6731
6732 3339968 x -= viewport.x;
6733 3339968 y -= viewport.y;
6734
6735
2/2
✓ Branch 0 taken 37656 times.
✓ Branch 1 taken 3302312 times.
3339968 if(scr->door[0]==dBOMBED)
6736 {
6737 37656 over_door(scr,dest,39,up,x,y);
6738 37656 }
6739
6740
2/2
✓ Branch 0 taken 36495 times.
✓ Branch 1 taken 3303473 times.
3339968 if(scr->door[1]==dBOMBED)
6741 {
6742 36495 over_door(scr,dest,135,down,x,y);
6743 36495 }
6744
6745
2/2
✓ Branch 0 taken 40440 times.
✓ Branch 1 taken 3299528 times.
3339968 if(scr->door[2]==dBOMBED)
6746 {
6747 40440 over_door(scr,dest,66,left,x,y);
6748 40440 }
6749
6750
2/2
✓ Branch 0 taken 37063 times.
✓ Branch 1 taken 3302905 times.
3339968 if(scr->door[3]==dBOMBED)
6751 {
6752 37063 over_door(scr,dest,77,right,x,y);
6753 37063 }
6754 3339968 }
6755 232437406 static inline bool standing_on_z(newcombo const& cmb, zfix const& standing_z_state)
6756 {
6757 232437406 zfix cmb_z, cmb_z_step;
6758
4/4
✓ Branch 0 taken 92789 times.
✓ Branch 1 taken 232344617 times.
✓ Branch 2 taken 88819 times.
✓ Branch 3 taken 3970 times.
232437406 if(cmb.type == cCSWITCHBLOCK && (cmb.usrflags & cflag9))
6759 {
6760 3970 cmb_z = zslongToFix(cmb.attributes[2]);
6761
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3970 times.
3970 cmb_z_step = zslongToFix(zc_max(0,cmb.attributes[3]));
6762 3970 }
6763
2/2
✓ Branch 0 taken 1983 times.
✓ Branch 1 taken 232431453 times.
232433436 else if(cmb.genflags & cflag3)
6764 {
6765 1983 cmb_z = cmb.z_height;
6766
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1983 times.
1983 cmb_z_step = zc_max(0_zf,cmb.z_step_height);
6767 1983 }
6768 232431453 else return false;
6769
6770
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5953 times.
✓ Branch 2 taken 4804 times.
✓ Branch 3 taken 1149 times.
5953 return (standing_z_state < 0 || (cmb_z>0 && (cmb_z - cmb_z_step) <= standing_z_state));
6771 232437406 }
6772 56117554 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt)
6773 {
6774 56117554 return _walkflag(zx,zy,cnt,0_zf);
6775 }
6776
6777 132920557 bool _walkflag_new(const mapscr* s0, const mapscr* s1, const mapscr* s2, zfix_round zx, zfix_round zy, zfix const& standing_z_state, bool is_temp_screens)
6778 {
6779 132920557 int x = zx.getRound(), y = zy.getRound();
6780 132920557 int pos = COMBOPOS(x % 256, y % 176);
6781 132920557 const newcombo& c = combobuf[s0->data[pos]];
6782 132920557 const newcombo& c1 = combobuf[s1->data[pos]];
6783 132920557 const newcombo& c2 = combobuf[s2->data[pos]];
6784
4/4
✓ Branch 0 taken 130925116 times.
✓ Branch 1 taken 1995441 times.
✓ Branch 2 taken 130915656 times.
✓ Branch 3 taken 9460 times.
266043402 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
6785
4/4
✓ Branch 0 taken 101153 times.
✓ Branch 1 taken 131016791 times.
✓ Branch 2 taken 2101809 times.
✓ Branch 3 taken 4245 times.
132920557 (iswater_type(c2.type))) && DRIEDLAKE);
6786 133122845 int32_t b=1;
6787
2/2
✓ Branch 0 taken 65628844 times.
✓ Branch 1 taken 67494001 times.
133122845 if(x&8) b<<=2;
6788
2/2
✓ Branch 0 taken 62187453 times.
✓ Branch 1 taken 70935392 times.
133122845 if(y&8) b<<=1;
6789
6790 133122845 int32_t cwalkflag = c.walk;
6791
4/4
✓ Branch 0 taken 133021701 times.
✓ Branch 1 taken 101144 times.
✓ Branch 2 taken 133021537 times.
✓ Branch 3 taken 164 times.
133122845 if(is_temp_screens && standing_on_z(c,standing_z_state)) cwalkflag &= (c.walk>>4)^0xF;
6792
8/10
✓ Branch 0 taken 50572 times.
✓ Branch 1 taken 133072109 times.
✓ Branch 2 taken 2096585 times.
✓ Branch 3 taken 2046013 times.
✓ Branch 4 taken 2096585 times.
✓ Branch 5 taken 133021537 times.
✓ Branch 6 taken 2096585 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2096585 times.
✗ Branch 9 not taken.
133122681 else if ((c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) || (iswater_type(c.type) && ((c.walk>>4)&b) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
6793
2/2
✓ Branch 0 taken 63476776 times.
✓ Branch 1 taken 69544925 times.
133021701 if (s1 != s0)
6794 {
6795
3/4
✓ Branch 0 taken 69544925 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 69544307 times.
✓ Branch 3 taken 618 times.
69544925 if(is_temp_screens && standing_on_z(c1,standing_z_state)) cwalkflag &= (c1.walk>>4)^0xF;
6796
4/10
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 69532578 times.
✓ Branch 2 taken 11729 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11729 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
69544307 else if ((iswater_type(c1.type) && ((c1.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_1) && !((c1.usrflags&cflag3) || (c1.usrflags&cflag4)))) cwalkflag &= c1.walk;
6797
2/2
✓ Branch 0 taken 62906 times.
✓ Branch 1 taken 69481401 times.
69544307 else if (c1.type == cBRIDGE)
6798 {
6799
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62906 times.
62906 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
6800 {
6801 62906 int efflag = (c1.walk & 0xF0)>>4;
6802 62906 int newsolid = (c1.walk & 0xF);
6803 62906 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
6804 62906 }
6805 else cwalkflag &= c1.walk;
6806 62906 }
6807
3/8
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 69469672 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11729 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
69481401 else if ((iswater_type(c1.type) && get_qr(qr_WATER_ON_LAYER_1) && ((c1.usrflags&cflag3) || (c1.usrflags&cflag4)) && ((c1.walk>>4)&b))) cwalkflag = 0;
6808 69481401 else cwalkflag |= c1.walk;
6809 69544925 }
6810
2/2
✓ Branch 0 taken 103150921 times.
✓ Branch 1 taken 29870780 times.
133021701 if (s2 != s0)
6811 {
6812
2/4
✓ Branch 0 taken 29870780 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 29870780 times.
✗ Branch 3 not taken.
29870780 if(is_temp_screens && standing_on_z(c2,standing_z_state)) cwalkflag &= (c2.walk>>4)^0xF;
6813
4/10
✓ Branch 0 taken 2154 times.
✓ Branch 1 taken 29868626 times.
✓ Branch 2 taken 2154 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2154 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
29870780 else if ((iswater_type(c2.type) && ((c2.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_2) && !((c2.usrflags&cflag3) || (c2.usrflags&cflag4)))) cwalkflag &= c2.walk;
6814
2/2
✓ Branch 0 taken 4447 times.
✓ Branch 1 taken 29866333 times.
29870780 else if (c2.type == cBRIDGE)
6815 {
6816
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4447 times.
4447 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
6817 {
6818 4447 int efflag = (c2.walk & 0xF0)>>4;
6819 4447 int newsolid = (c2.walk & 0xF);
6820 4447 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
6821 4447 }
6822 else cwalkflag &= c2.walk;
6823 4447 }
6824
3/8
✓ Branch 0 taken 2154 times.
✓ Branch 1 taken 29864179 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2154 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
29866333 else if ((iswater_type(c2.type) && get_qr(qr_WATER_ON_LAYER_2) && ((c2.usrflags&cflag3) || (c2.usrflags&cflag4))) && ((c2.walk>>4)&b)) cwalkflag = 0;
6825 29866333 else cwalkflag |= c2.walk;
6826 29870780 }
6827
6828
4/4
✓ Branch 0 taken 29568194 times.
✓ Branch 1 taken 103453507 times.
✓ Branch 2 taken 948 times.
✓ Branch 3 taken 29567246 times.
133021701 if((cwalkflag&b) && !dried)
6829 29567246 return true;
6830
6831
3/4
✓ Branch 0 taken 103454455 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103438044 times.
✓ Branch 3 taken 16411 times.
103454455 if (is_temp_screens && collide_object(zx, zy, 0.0001_zf, 0.0001_zf)) return true;
6832
6833 103438044 return false;
6834 133021701 }
6835
6836 // Returns true if the combo at viewport position x,y is solid. Looks at a combo's quadrant walkablity flags.
6837 133021701 static bool _walkflag_new(zfix_round zx, zfix_round zy, zfix const& standing_z_state)
6838 {
6839 133021701 int x = zx.getRound(), y = zy.getRound();
6840 133021701 mapscr* s0 = get_scr_for_world_xy_layer(x, y, 0);
6841 133021701 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
6842 133021701 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
6843
2/2
✓ Branch 0 taken 63476776 times.
✓ Branch 1 taken 69544925 times.
133021701 if (!s1->valid) s1 = s0;
6844
2/2
✓ Branch 0 taken 103150921 times.
✓ Branch 1 taken 29870780 times.
133021701 if (!s2->valid) s2 = s0;
6845 133021701 return _walkflag_new(s0, s1, s2, zx, zy, standing_z_state, true);
6846 }
6847
6848 128587950 bool _walkflag(zfix_round x,zfix_round y,int32_t cnt,zfix const& standing_z_state)
6849 {
6850 128587950 int max_x = world_w;
6851 128587950 int max_y = world_h;
6852
2/2
✓ Branch 0 taken 68545213 times.
✓ Branch 1 taken 60042737 times.
128587950 if (!get_qr(qr_LTTPWALK))
6853 {
6854 60042737 max_x -= 7;
6855 60042737 max_y -= 7;
6856 60042737 }
6857
4/4
✓ Branch 0 taken 128317118 times.
✓ Branch 1 taken 270832 times.
✓ Branch 2 taken 83268 times.
✓ Branch 3 taken 128233850 times.
128587950 if (x < 0 || y < 0) return false;
6858
2/2
✓ Branch 0 taken 322356 times.
✓ Branch 1 taken 127911494 times.
128233850 if (x >= max_x) return false;
6859
3/4
✓ Branch 0 taken 539663 times.
✓ Branch 1 taken 127371831 times.
✓ Branch 2 taken 539663 times.
✗ Branch 3 not taken.
127911494 if (x >= max_x - 8 && cnt == 2) return false;
6860
2/2
✓ Branch 0 taken 127362270 times.
✓ Branch 1 taken 549224 times.
127911494 if (y >= max_y) return false;
6861
6862
4/4
✓ Branch 0 taken 29465504 times.
✓ Branch 1 taken 97896766 times.
✓ Branch 2 taken 92237335 times.
✓ Branch 3 taken 5659431 times.
127362270 return _walkflag_new(x, y, standing_z_state) || (cnt != 1 && _walkflag_new(x + 8, y, standing_z_state));
6863 128587950 }
6864
6865 99143846 static bool effectflag(int32_t x, int32_t y, int32_t layer)
6866 {
6867 99143846 mapscr* s0 = get_scr_for_world_xy(x, y);
6868 99143846 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
6869 99143846 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
6870
2/2
✓ Branch 0 taken 51514522 times.
✓ Branch 1 taken 47629324 times.
99143846 if (!s1->valid) s1 = s0;
6871
2/2
✓ Branch 0 taken 17652787 times.
✓ Branch 1 taken 81491059 times.
99143846 if (!s2->valid) s2 = s0;
6872
6873 99143846 int pos = COMBOPOS(x % 256, y % 176);
6874 99143846 const newcombo& c = combobuf[s0->data[pos]];
6875 99143846 const newcombo& c1 = combobuf[s1->data[pos]];
6876 99143846 const newcombo& c2 = combobuf[s2->data[pos]];
6877
4/4
✓ Branch 0 taken 98216568 times.
✓ Branch 1 taken 927278 times.
✓ Branch 2 taken 98215202 times.
✓ Branch 3 taken 1366 times.
198287692 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
6878
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 98215202 times.
✓ Branch 2 taken 926808 times.
✓ Branch 3 taken 1836 times.
99143846 (iswater_type(c2.type))) && DRIEDLAKE);
6879 99143846 int32_t b=1;
6880
2/2
✓ Branch 0 taken 49874777 times.
✓ Branch 1 taken 49269069 times.
99143846 if(x&8) b<<=2;
6881
2/2
✓ Branch 0 taken 41816616 times.
✓ Branch 1 taken 57327230 times.
99143846 if(y&8) b<<=1;
6882
6883 99143846 int32_t cwalkflag = (c.walk>>4);
6884
2/2
✓ Branch 0 taken 76350253 times.
✓ Branch 1 taken 22793593 times.
99143846 if (layer == 0) cwalkflag = (c1.walk>>4);
6885
2/2
✓ Branch 0 taken 76351451 times.
✓ Branch 1 taken 22792395 times.
99143846 if (layer == 1) cwalkflag = (c2.walk>>4);
6886 //if (c.type == cBRIDGE || (iswater_type(c.type) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
6887
4/4
✓ Branch 0 taken 51514522 times.
✓ Branch 1 taken 47629324 times.
✓ Branch 2 taken 22464483 times.
✓ Branch 3 taken 29050039 times.
99143846 if (s1 != s0 && layer < 0)
6888 {
6889
2/2
✓ Branch 0 taken 22451077 times.
✓ Branch 1 taken 13406 times.
22464483 if (c1.type == cBRIDGE) cwalkflag &= (~(c1.walk>>4));
6890 22464483 }
6891
4/4
✓ Branch 0 taken 17652787 times.
✓ Branch 1 taken 81491059 times.
✓ Branch 2 taken 13091910 times.
✓ Branch 3 taken 4560877 times.
99143846 if (s2 != s0 && layer < 1)
6892 {
6893
2/2
✓ Branch 0 taken 13086050 times.
✓ Branch 1 taken 5860 times.
13091910 if (c2.type == cBRIDGE) cwalkflag &= (~(c2.walk>>4));
6894 13091910 }
6895
6896
2/2
✓ Branch 0 taken 98984592 times.
✓ Branch 1 taken 159254 times.
99143846 return (cwalkflag&b) ? !dried : false;
6897 }
6898
6899 99518730 bool _effectflag(int32_t x,int32_t y,int32_t cnt, int32_t layer, bool notLink)
6900 {
6901 DCHECK(cnt == 0 || cnt == 1);
6902 99518730 int max_x = world_w;
6903 99518730 int max_y = world_h;
6904
3/4
✓ Branch 0 taken 45833723 times.
✓ Branch 1 taken 53685007 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45833723 times.
99518730 if (!get_qr(qr_LTTPWALK) && !notLink)
6905 {
6906 45833723 max_x -= 7;
6907 45833723 max_y -= 7;
6908 45833723 }
6909
4/4
✓ Branch 0 taken 99517977 times.
✓ Branch 1 taken 753 times.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 99517773 times.
99518730 if (x < 0 || y < 0) return false;
6910
2/2
✓ Branch 0 taken 818 times.
✓ Branch 1 taken 99516955 times.
99517773 if (x >= max_x) return false;
6911
3/4
✓ Branch 0 taken 521780 times.
✓ Branch 1 taken 98995175 times.
✓ Branch 2 taken 521780 times.
✗ Branch 3 not taken.
99516955 if (x >= max_x - 8 && cnt == 2) return false;
6912
2/2
✓ Branch 0 taken 373109 times.
✓ Branch 1 taken 99143846 times.
99516955 if (y >= max_y) return false;
6913
6914
3/4
✓ Branch 0 taken 98983802 times.
✓ Branch 1 taken 160044 times.
✓ Branch 2 taken 160044 times.
✗ Branch 3 not taken.
99143846 return effectflag(x, y, layer) || (cnt == 2 && effectflag(x + 8, y, layer));
6915 99518730 }
6916
6917 // used by mapdata->isSolid(x,y) in ZScript
6918 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
6919 {
6920 int x = zx.getRound(), y = zy.getRound();
6921 {
6922 int max_x = 256;
6923 int max_y = 176;
6924 if (!get_qr(qr_LTTPWALK))
6925 {
6926 max_x -= 7;
6927 max_y -= 7;
6928 }
6929 if (x < 0 || y < 0) return false;
6930 if (x >= max_x) return false;
6931 if (x >= max_x - 8 && cnt == 2) return false;
6932 if (y >= max_y) return false;
6933 }
6934
6935 const mapscr *s1, *s2;
6936
6937 if ( m->layermap[0] > 0 )
6938 {
6939 s1 = get_canonical_scr(m->layermap[0], m->layerscreen[0]);
6940 }
6941 else s1 = m;
6942
6943 if ( m->layermap[1] > 0 )
6944 {
6945 s2 = get_canonical_scr(m->layermap[1], m->layerscreen[1]);
6946 }
6947 else s2 = m;
6948
6949 zfix unused;
6950 return _walkflag_new(m, s1, s2, x, y, unused, false) || (cnt != 1 && _walkflag_new(m, s1, s2, x + 8, y, unused, false));
6951 }
6952
6953 bool _walkflag_layer(zfix_round x, zfix_round y, int32_t layer, int32_t cnt)
6954 {
6955 DCHECK_LAYER_NEG1_INDEX(layer);
6956 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
6957 if (!m->is_valid()) return false;
6958 return _walkflag_layer(x, y, cnt, m);
6959 }
6960
6961 static bool _walkflag_layer_new(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m, int max_x, int max_y)
6962 {
6963 int x = zx.getRound(), y = zy.getRound();
6964
6965 if (!get_qr(qr_LTTPWALK))
6966 {
6967 max_x -= 7;
6968 max_y -= 7;
6969 }
6970 if (x < 0 || y < 0) return false;
6971 if (x >= max_x) return false;
6972 if (x >= max_x - 8 && cnt == 2) return false;
6973 if (y >= max_y) return false;
6974
6975 if(!m) return true;
6976
6977 int pos = COMBOPOS(x%256, y%176);
6978 const newcombo* c = &combobuf[m->data[pos]];
6979 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
6980 int32_t b=1;
6981
6982 if(x&8) b<<=2;
6983
6984 if(y&8) b<<=1;
6985
6986 if((c->walk&b) && !dried)
6987 return true;
6988
6989 if(cnt==1) return false;
6990
6991 ++pos;
6992
6993 if(!(x&8))
6994 b<<=2;
6995 else
6996 {
6997 c = &combobuf[m->data[pos]];
6998 dried = ((iswater_type(c->type)) && DRIEDLAKE);
6999 b=1;
7000
7001 if(y&8) b<<=1;
7002 }
7003
7004 return (c->walk&b) ? !dried : false;
7005 }
7006
7007 //Only check the given mapscr*, not its layer 1&2
7008 bool _walkflag_layer(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7009 {
7010 return _walkflag_layer_new(zx, zy, cnt, m, world_w, world_h);
7011 }
7012
7013 bool _walkflag_layer_scrolling(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7014 {
7015 return _walkflag_layer_new(zx, zy, cnt, m, scrolling_region.width, scrolling_region.height);
7016 }
7017
7018 313446 bool _effectflag_layer(int32_t x, int32_t y, int32_t layer, int32_t cnt, bool notLink)
7019 {
7020 DCHECK_LAYER_NEG1_INDEX(layer);
7021 313446 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
7022
2/2
✓ Branch 0 taken 1762 times.
✓ Branch 1 taken 311684 times.
313446 if (!m->is_valid()) return false;
7023 311684 return _effectflag_layer(x, y, cnt, m, notLink);
7024 313446 }
7025
7026 377717 bool _effectflag_layer(int32_t x,int32_t y,int32_t cnt, mapscr* m, bool notLink)
7027 {
7028 377717 int max_x = world_w;
7029 377717 int max_y = world_h;
7030
3/4
✓ Branch 0 taken 50002 times.
✓ Branch 1 taken 327715 times.
✓ Branch 2 taken 50002 times.
✗ Branch 3 not taken.
377717 if (!get_qr(qr_LTTPWALK) && !notLink)
7031 {
7032 max_x -= 7;
7033 max_y -= 7;
7034 }
7035
2/4
✓ Branch 0 taken 377717 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 377717 times.
377717 if (x < 0 || y < 0) return false;
7036
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 377717 times.
377717 if (x >= max_x) return false;
7037
3/4
✓ Branch 0 taken 1209 times.
✓ Branch 1 taken 376508 times.
✓ Branch 2 taken 1209 times.
✗ Branch 3 not taken.
377717 if (x >= max_x - 8 && cnt == 2) return false;
7038
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 377717 times.
377717 if (y >= max_y) return false;
7039
7040
1/2
✓ Branch 0 taken 377717 times.
✗ Branch 1 not taken.
377717 if (!m) return true;
7041
7042 377717 int pos = COMBOPOS(x%256, y%176);
7043 377717 const newcombo* c = &combobuf[m->data[pos]];
7044
3/4
✓ Branch 0 taken 377336 times.
✓ Branch 1 taken 381 times.
✓ Branch 2 taken 381 times.
✗ Branch 3 not taken.
378098 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
7045 377717 int32_t b=1;
7046
7047
2/2
✓ Branch 0 taken 205340 times.
✓ Branch 1 taken 172377 times.
377717 if(x&8) b<<=2;
7048
7049
2/2
✓ Branch 0 taken 157087 times.
✓ Branch 1 taken 220630 times.
377717 if(y&8) b<<=1;
7050
7051
3/4
✓ Branch 0 taken 308723 times.
✓ Branch 1 taken 68994 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 308723 times.
377717 if(((c->walk>>4)&b) && !dried)
7052 308723 return true;
7053
7054
1/2
✓ Branch 0 taken 68994 times.
✗ Branch 1 not taken.
68994 if(cnt==1) return false;
7055
7056 ++pos;
7057
7058 if(!(x&8))
7059 b<<=2;
7060 else
7061 {
7062 c = &combobuf[m->data[pos]];
7063 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7064 b=1;
7065
7066 if(y&8) b<<=1;
7067 }
7068
7069 return ((c->walk>>4)&b) ? !dried : false;
7070 377717 }
7071
7072 812605 bool water_walkflag(int32_t x, int32_t y, int32_t cnt)
7073 {
7074 812605 int max_x = world_w;
7075 812605 int max_y = world_h;
7076
2/2
✓ Branch 0 taken 117367 times.
✓ Branch 1 taken 695238 times.
812605 if (!get_qr(qr_LTTPWALK))
7077 {
7078 695238 max_x -= 7;
7079 695238 max_y -= 7;
7080 695238 }
7081
2/4
✓ Branch 0 taken 812605 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 812605 times.
812605 if (x < 0 || y < 0) return false;
7082
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
812605 if (x >= max_x) return false;
7083
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
812605 if (x >= max_x - 8 && cnt == 2) return false;
7084
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
812605 if (y >= max_y) return false;
7085
7086
3/4
✓ Branch 0 taken 16825 times.
✓ Branch 1 taken 795780 times.
✓ Branch 2 taken 795780 times.
✗ Branch 3 not taken.
812605 return water_walkflag(x, y) || (cnt != 1 && water_walkflag(x + 8, y));
7087 812605 }
7088
7089 812605 bool water_walkflag(int32_t x, int32_t y)
7090 {
7091 812605 const newcombo& c = combobuf[MAPCOMBO2(-1, x, y)];
7092 812605 const newcombo& c1 = combobuf[MAPCOMBO2(0, x, y)];
7093 812605 const newcombo& c2 = combobuf[MAPCOMBO2(1, x, y)];
7094
7095 812605 int32_t b=1;
7096
2/2
✓ Branch 0 taken 414677 times.
✓ Branch 1 taken 397928 times.
812605 if(x&8) b<<=2;
7097
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
812605 if(y&8) b<<=1;
7098
7099
2/2
✓ Branch 0 taken 26377 times.
✓ Branch 1 taken 786228 times.
812605 if(get_qr(qr_NO_SOLID_SWIM))
7100 {
7101
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 26245 times.
26377 if(c.walk&b)
7102 132 return true;
7103
7104
2/2
✓ Branch 0 taken 292 times.
✓ Branch 1 taken 25953 times.
26245 if(c1.walk&b)
7105 292 return true;
7106
7107
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25953 times.
25953 if(c2.walk&b)
7108 return true;
7109 25953 }
7110 else
7111 {
7112
4/4
✓ Branch 0 taken 36133 times.
✓ Branch 1 taken 750095 times.
✓ Branch 2 taken 19762 times.
✓ Branch 3 taken 16371 times.
786228 if((c.walk&b) && !iswater_type(c.type))
7113 16371 return true;
7114
7115
3/4
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 769840 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
769857 if((c1.walk&b) && !iswater_type(c1.type))
7116 17 return true;
7117
7118
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 769827 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
769840 if((c2.walk&b) && !iswater_type(c2.type))
7119 13 return true;
7120 }
7121
7122 795780 return false;
7123 812605 }
7124
7125 564116 bool hit_walkflag(int32_t x,int32_t y,int32_t cnt)
7126 {
7127
2/2
✓ Branch 0 taken 90999 times.
✓ Branch 1 taken 473117 times.
564116 if(dlevel)
7128
8/8
✓ Branch 0 taken 471712 times.
✓ Branch 1 taken 1405 times.
✓ Branch 2 taken 468517 times.
✓ Branch 3 taken 3195 times.
✓ Branch 4 taken 466857 times.
✓ Branch 5 taken 1660 times.
✓ Branch 6 taken 4199 times.
✓ Branch 7 taken 462658 times.
473117 if(x<32 || y<40 || (x+(cnt-1)*8)>=world_w-32 || y>=world_h-32)
7129 10459 return true;
7130
7131
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 553655 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
553657 if(blockpath && y<((get_qr(qr_LTTPCOLLISION))?80:88))
7132 return true;
7133
7134
8/8
✓ Branch 0 taken 553388 times.
✓ Branch 1 taken 269 times.
✓ Branch 2 taken 553155 times.
✓ Branch 3 taken 233 times.
✓ Branch 4 taken 552946 times.
✓ Branch 5 taken 209 times.
✓ Branch 6 taken 346 times.
✓ Branch 7 taken 552600 times.
553657 if(x<16 || y<16 || (x+(cnt-1)*8)>=world_w-16 || y>=world_h-16)
7135 1057 return true;
7136
7137 // for(int32_t i=0; i<4; i++)
7138
4/4
✓ Branch 0 taken 841 times.
✓ Branch 1 taken 551759 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 805 times.
552600 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7139 36 return true;
7140
7141
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 552564 times.
552564 if (collide_object(x, y,cnt*8, 1))
7142 return true;
7143
7144 552564 return _walkflag(x,y,cnt);
7145 564116 }
7146
7147 12110 bool solpush_walkflag(int32_t x, int32_t y, int32_t cnt, solid_object const* ign)
7148 {
7149 // 16 pixel buffer to account for slopes that are on bordering screens.
7150
4/8
✓ Branch 0 taken 12110 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12110 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12110 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 12110 times.
12110 if(x<0 || y<0 || x>=world_w+16 || y>=world_h+16)
7151 return true;
7152
7153 // for(int32_t i=0; i<4; i++)
7154
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12110 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12110 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7155 return true;
7156
7157
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12110 times.
12110 if (collide_object(x, y,cnt*8, 1, ign))
7158 return true;
7159
7160 12110 return _walkflag(x,y,cnt);
7161 12110 }
7162
7163 37843 void map_bkgsfx(bool on)
7164 {
7165
2/2
✓ Branch 0 taken 37822 times.
✓ Branch 1 taken 21 times.
37843 if(on)
7166 {
7167 37822 cont_sfx(hero_scr->oceansfx);
7168
7169
4/4
✓ Branch 0 taken 369 times.
✓ Branch 1 taken 37453 times.
✓ Branch 2 taken 315 times.
✓ Branch 3 taken 54 times.
37822 if(hero_scr->bosssfx && !(game->lvlitems[dlevel]&liBOSS))
7170 315 cont_sfx(hero_scr->bosssfx);
7171 37822 }
7172 else
7173 {
7174 21 adjust_sfx(hero_scr->oceansfx,128,false);
7175 21 adjust_sfx(hero_scr->bosssfx,128,false);
7176
7177
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 21 times.
135 for(int32_t i=0; i<guys.Count(); i++)
7178 {
7179
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 84 times.
114 if(((enemy*)guys.spr(i))->bgsfx)
7180 84 stop_sfx(((enemy*)guys.spr(i))->bgsfx);
7181 114 }
7182 }
7183 37843 }
7184
7185 239 void toggle_switches(dword flags, bool entry)
7186 {
7187
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 239 times.
239 if(!flags) return; //No flags to toggle
7188
7189 478 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7190 239 toggle_switches(flags, entry, create_screen_handles(scr));
7191 239 });
7192 239 }
7193 54050 void toggle_switches(dword flags, bool entry, const screen_handles_t& screen_handles)
7194 {
7195
2/2
✓ Branch 0 taken 737 times.
✓ Branch 1 taken 53313 times.
54050 if(!flags) return; //No flags to toggle
7196
7197 737 mapscr* m = screen_handles[0].base_scr;
7198 737 int screen = m->screen;
7199 737 bool is_active_screen = is_in_current_region(m);
7200
7201 305041 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
7202 304304 byte togglegrid[176] = {0};
7203 304304 mapscr* scr = rpos_handle.scr;
7204 304304 int lyr = rpos_handle.layer;
7205 304304 int pos = rpos_handle.pos;
7206 304304 newcombo const& cmb = combobuf[scr->data[pos]];
7207
2/2
✓ Branch 0 taken 39424 times.
✓ Branch 1 taken 264880 times.
304304 if(is_active_screen)
7208
1/2
✓ Branch 0 taken 264880 times.
✗ Branch 1 not taken.
367773 trig_each_combo_trigger(rpos_handle, [&](combo_trigger const& trig){
7209
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 102893 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
102893 return trig.trigger_flags.get(TRIGFLAG_TRIGLEVELSTATE) && trig.trig_lstate < 32 && (flags&(1<<trig.trig_lstate));
7210 }, ctrigSWITCHSTATE);
7211
3/4
✓ Branch 0 taken 303641 times.
✓ Branch 1 taken 663 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2760 times.
304304 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32
7212
2/2
✓ Branch 0 taken 2760 times.
✓ Branch 1 taken 301544 times.
304304 && !(cmb.usrflags & cflag11)) //global state
7213 {
7214
2/2
✓ Branch 0 taken 446 times.
✓ Branch 1 taken 2314 times.
2760 if(flags&(1<<cmb.attribytes[0]))
7215 {
7216 2314 set<int32_t> oldData;
7217 //Increment the combo/cset by the attributes
7218 2314 int32_t cmbofs = (cmb.attributes[0]/10000L);
7219 2314 int32_t csofs = (cmb.attributes[1]/10000L);
7220
1/2
✓ Branch 0 taken 2314 times.
✗ Branch 1 not taken.
2314 oldData.insert(scr->data[pos]);
7221
1/2
✓ Branch 0 taken 2314 times.
✗ Branch 1 not taken.
2314 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7222 2314 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7223
4/4
✓ Branch 0 taken 1435 times.
✓ Branch 1 taken 879 times.
✓ Branch 2 taken 1197 times.
✓ Branch 3 taken 238 times.
2314 if(entry && (cmb.usrflags&cflag8))
7224 {
7225 238 newcombo const* tmp = &combobuf[scr->data[pos]];
7226
2/4
✓ Branch 0 taken 238 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 238 times.
✗ Branch 3 not taken.
238 while(tmp->can_cycle())
7227 {
7228 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7229 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7230 if(oldData.find(cid) != oldData.end())
7231 break;
7232
7233 scr->data[pos] = cid;
7234 if(!(tmp->animflags & AF_CYCLENOCSET))
7235 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7236 oldData.insert(cid);
7237 tmp = &combobuf[cid];
7238 }
7239 238 }
7240 2314 int32_t cmbid = scr->data[pos];
7241
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 2273 times.
2314 if(combobuf[cmbid].animflags & AF_CYCLE)
7242 {
7243 41 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7244 41 combobuf[cmbid].cur_frame=0;
7245 41 combobuf[cmbid].aclk = 0;
7246
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 combo_caches::drawing.refresh(cmbid);
7247 41 }
7248 2314 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7249
2/2
✓ Branch 0 taken 511 times.
✓ Branch 1 taken 1803 times.
2314 if(cmb.type == cCSWITCH) return; //Switches don't toggle other layers
7250
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2147 times.
2147 for(int32_t lyr2 = 0; lyr2 < 7; ++lyr2) //Toggle same pos on other layers, if flag set
7251 {
7252
2/2
✓ Branch 0 taken 1671 times.
✓ Branch 1 taken 476 times.
2147 if(lyr==lyr2) return;
7253
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 344 times.
476 if(!(cmb.usrflags&(1<<lyr2))) return;
7254
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 if(togglegrid[pos]&(1<<lyr2)) return;
7255
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
344 mapscr* scr_2 = (lyr2 ? get_scr_layer(screen, lyr2) : m);
7256
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 if(!scr_2->data[pos]) //Don't increment empty space
7257 return;
7258 344 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7259
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
344 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK) && !(cmb.usrflags & cflag11)
7260 && cmb_2.attribytes[0] < 32 && (flags&(1<<cmb_2.attribytes[0])))
7261 return; //This is a switch/block that will be hit later in the loop!
7262 344 set<int32_t> oldData2;
7263 //Increment the combo/cset by the original cmb's attributes
7264
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 oldData2.insert(scr_2->data[pos]);
7265
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7266 344 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7267
3/4
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 294 times.
✓ Branch 2 taken 50 times.
✗ Branch 3 not taken.
344 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7268 {
7269 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7270 while(tmp->can_cycle())
7271 {
7272 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7273 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7274 if(oldData2.find(cid) != oldData2.end())
7275 break;
7276
7277 scr_2->data[pos] = cid;
7278 if(!(tmp->animflags & AF_CYCLENOCSET))
7279 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7280 oldData2.insert(cid);
7281 tmp = &combobuf[cid];
7282 }
7283 }
7284 344 int32_t cmbid2 = scr_2->data[pos];
7285
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
344 if(combobuf[cmbid2].animflags & AF_CYCLE)
7286 {
7287 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7288 combobuf[cmbid2].cur_frame=0;
7289 combobuf[cmbid2].aclk = 0;
7290 combo_caches::drawing.refresh(cmbid2);
7291 }
7292 344 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7293 344 }
7294
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 2314 times.
✗ Branch 2 not taken.
2314 }
7295 446 }
7296 304304 });
7297
7298
3/4
✓ Branch 0 taken 519 times.
✓ Branch 1 taken 218 times.
✓ Branch 2 taken 519 times.
✗ Branch 3 not taken.
737 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7299 {
7300 newcombo const& cmb = combobuf[mblock2.bcombo];
7301 if(!(cmb.usrflags & cflag11) && (cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32)
7302 {
7303 if(flags&(1<<cmb.attribytes[0]))
7304 {
7305 //Increment the combo/cset by the attributes
7306 int32_t cmbofs = (cmb.attributes[0]/10000L);
7307 int32_t csofs = (cmb.attributes[1]/10000L);
7308 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7309 mblock2.cs = (mblock2.cs + csofs) & 15;
7310 int32_t cmbid = mblock2.bcombo;
7311 if(combobuf[cmbid].animflags & AF_CYCLE)
7312 {
7313 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7314 combobuf[cmbid].cur_frame=0;
7315 combobuf[cmbid].aclk = 0;
7316 combo_caches::drawing.refresh(cmbid);
7317 }
7318 }
7319 }
7320 }
7321
7322
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 513 times.
737 if (is_active_screen)
7323 {
7324 513 int screen_index_offset = get_region_screen_offset(m->screen);
7325 513 word c = m->numFFC();
7326
2/2
✓ Branch 0 taken 334 times.
✓ Branch 1 taken 513 times.
847 for (int q = 0; q < c; ++q)
7327 {
7328 334 auto ffc_handle = *m->getFFCHandle(q, screen_index_offset);
7329
1/2
✓ Branch 0 taken 334 times.
✗ Branch 1 not taken.
363 trig_each_combo_trigger(ffc_handle, [&](combo_trigger const& trig){
7330
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 29 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
29 return trig.trigger_flags.get(TRIGFLAG_TRIGLEVELSTATE) && trig.trig_lstate < 32 && (flags&(1<<trig.trig_lstate));
7331 }, ctrigSWITCHSTATE);
7332 334 }
7333 513 }
7334 54050 }
7335
7336 1 void toggle_gswitches(int32_t state, bool entry)
7337 {
7338 2 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7339 1 toggle_gswitches(state, entry, create_screen_handles(scr));
7340 1 });
7341 1 }
7342 1 void toggle_gswitches(int32_t state, bool entry, const screen_handles_t& screen_handles)
7343 {
7344 1 bool states[256] = {false};
7345 1 states[state] = true;
7346 1 toggle_gswitches(states, entry, screen_handles);
7347 1 }
7348 15216338 void toggle_gswitches(bool* states, bool entry, const screen_handles_t& screen_handles)
7349 {
7350
1/2
✓ Branch 0 taken 15216338 times.
✗ Branch 1 not taken.
15216338 if(!states) return;
7351
7352 15216338 auto& combo_cache = combo_caches::gswitch;
7353 15216338 mapscr* base_scr = screen_handles[0].base_scr;
7354 15216338 int screen = base_scr->screen;
7355 15216338 bool is_active_screen = is_in_current_region(base_scr);
7356 15216338 byte togglegrid[176] = {0};
7357
2/2
✓ Branch 0 taken 15216338 times.
✓ Branch 1 taken 106514366 times.
121730704 for(int32_t lyr = 0; lyr <= 6; ++lyr)
7358 {
7359 106514366 mapscr* scr = screen_handles[lyr].scr;
7360
2/2
✓ Branch 0 taken 32314156 times.
✓ Branch 1 taken 74200210 times.
106514366 if (!scr)
7361 74200210 continue;
7362
7363
2/2
✓ Branch 0 taken 32314156 times.
✓ Branch 1 taken 5687291456 times.
5719605612 for(int32_t pos = 0; pos < 176; ++pos)
7364 {
7365 5687291456 int cid = scr->data[pos];
7366 5687291456 auto& mini_cmb = combo_cache.minis[cid];
7367
7368
2/2
✓ Branch 0 taken 93475360 times.
✓ Branch 1 taken 5593816096 times.
5687291456 if (is_active_screen)
7369 {
7370
2/2
✓ Branch 0 taken 5593814214 times.
✓ Branch 1 taken 1882 times.
5593816096 if (mini_cmb.trigger_global_state)
7371 {
7372 1882 auto rpos_handle = get_rpos_handle_for_screen(screen, lyr, pos);
7373
1/2
✓ Branch 0 taken 1882 times.
✗ Branch 1 not taken.
3764 trig_each_combo_trigger(rpos_handle, [&](combo_trigger const& trig){
7374
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1882 times.
1882 return trig.trigger_flags.get(TRIGFLAG_TRIGGLOBALSTATE) && states[trig.trig_gstate];
7375 }, ctrigSWITCHSTATE);
7376 1882 }
7377 5593816096 }
7378
7379
2/2
✓ Branch 0 taken 40395 times.
✓ Branch 1 taken 5687251061 times.
5687291456 if (!mini_cmb.has_global_state)
7380 5687251061 continue;
7381
7382 40395 newcombo const& cmb = combobuf[cid];
7383
2/4
✓ Branch 0 taken 40395 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 40395 times.
40395 if(cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK)
7384 {
7385 if(states[cmb.attribytes[0]])
7386 {
7387 set<int32_t> oldData;
7388 //Increment the combo/cset by the attributes
7389 int32_t cmbofs = (cmb.attributes[0]/10000L);
7390 int32_t csofs = (cmb.attributes[1]/10000L);
7391 oldData.insert(scr->data[pos]);
7392 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7393 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7394 if(entry && (cmb.usrflags&cflag8))
7395 {
7396 newcombo const* tmp = &combobuf[scr->data[pos]];
7397 while(tmp->can_cycle())
7398 {
7399 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7400 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7401 if(oldData.find(cid) != oldData.end())
7402 break;
7403 scr->data[pos] = cid;
7404 if(!(tmp->animflags & AF_CYCLENOCSET))
7405 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7406 oldData.insert(cid);
7407 tmp = &combobuf[cid];
7408 }
7409 }
7410 int32_t cmbid = scr->data[pos];
7411 if(combobuf[cmbid].animflags & AF_CYCLE)
7412 {
7413 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7414 combobuf[cmbid].cur_frame=0;
7415 combobuf[cmbid].aclk = 0;
7416 combo_caches::drawing.refresh(cmbid);
7417 }
7418 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7419 if(cmb.type == cCSWITCH) continue; //Switches don't toggle other layers
7420 for(int32_t lyr2 = 0; lyr2 <= 6; ++lyr2) //Toggle same pos on other layers, if flag set
7421 {
7422 if(lyr==lyr2) continue;
7423 if(!(cmb.usrflags&(1<<lyr2))) continue;
7424 if(togglegrid[pos]&(1<<lyr2)) continue;
7425 mapscr* scr_2 = lyr2 == 0 ? base_scr : get_scr_layer_valid(screen, lyr2);
7426 if(!scr_2 || !scr_2->data[pos]) //Don't increment empty space
7427 continue;
7428 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7429 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK)
7430 && (cmb_2.usrflags & cflag11) && (states[cmb_2.attribytes[0]]))
7431 continue; //This is a switch/block that will be hit later in the loop!
7432 set<int32_t> oldData2;
7433 //Increment the combo/cset by the original cmb's attributes
7434 oldData2.insert(scr_2->data[pos]);
7435 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7436 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7437 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7438 {
7439 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7440 while(tmp->can_cycle())
7441 {
7442 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7443 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7444 if(oldData2.find(cid) != oldData2.end())
7445 break;
7446 scr_2->data[pos] = cid;
7447 if(!(tmp->animflags & AF_CYCLENOCSET))
7448 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7449 oldData2.insert(cid);
7450 tmp = &combobuf[cid];
7451 }
7452 }
7453 int32_t cmbid2 = scr_2->data[pos];
7454 if(combobuf[cmbid2].animflags & AF_CYCLE)
7455 {
7456 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7457 combobuf[cmbid2].cur_frame=0;
7458 combobuf[cmbid2].aclk = 0;
7459 combo_caches::drawing.refresh(cmbid2);
7460 }
7461 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7462 }
7463 }
7464 }
7465 40395 }
7466 32314156 }
7467
7468
4/4
✓ Branch 0 taken 547045 times.
✓ Branch 1 taken 14669293 times.
✓ Branch 2 taken 542301 times.
✓ Branch 3 taken 4744 times.
15216338 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7469 {
7470 4744 newcombo const& cmb = combobuf[mblock2.bcombo];
7471
2/4
✓ Branch 0 taken 4744 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4744 times.
✗ Branch 3 not taken.
4744 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && (cmb.usrflags & cflag11))
7472 {
7473 if(states[cmb.attribytes[0]])
7474 {
7475 //Increment the combo/cset by the attributes
7476 int32_t cmbofs = (cmb.attributes[0]/10000L);
7477 int32_t csofs = (cmb.attributes[1]/10000L);
7478 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7479 mblock2.cs = (mblock2.cs + csofs) & 15;
7480 int32_t cmbid = mblock2.bcombo;
7481 if(combobuf[cmbid].animflags & AF_CYCLE)
7482 {
7483 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7484 combobuf[cmbid].cur_frame=0;
7485 combobuf[cmbid].aclk = 0;
7486 combo_caches::drawing.refresh(cmbid);
7487 }
7488 }
7489 }
7490 4744 }
7491
7492
2/2
✓ Branch 0 taken 413479 times.
✓ Branch 1 taken 14802859 times.
15216338 if(is_active_screen)
7493 {
7494 14802859 int screen_index_offset = get_region_screen_offset(screen);
7495 14802859 word c = base_scr->numFFC();
7496
2/2
✓ Branch 0 taken 441793312 times.
✓ Branch 1 taken 14802859 times.
456596171 for (int q = 0; q < c; ++q)
7497 {
7498 441793312 auto ffc_handle = *base_scr->getFFCHandle(q, screen_index_offset);
7499
1/2
✓ Branch 0 taken 441793312 times.
✗ Branch 1 not taken.
442022100 trig_each_combo_trigger(ffc_handle, [&](combo_trigger const& trig){
7500
1/2
✓ Branch 0 taken 228788 times.
✗ Branch 1 not taken.
228788 return trig.trigger_flags.get(TRIGFLAG_TRIGGLOBALSTATE) && states[trig.trig_gstate];
7501 }, ctrigSWITCHSTATE);
7502 441793312 }
7503 14802859 }
7504 15216338 }
7505 53811 void toggle_gswitches_load(const screen_handles_t& screen_handles)
7506 {
7507 bool states[256];
7508
2/2
✓ Branch 0 taken 13775616 times.
✓ Branch 1 taken 53811 times.
13829427 for(auto q = 0; q < 256; ++q)
7509 {
7510 13775616 states[q] = game->gswitch_timers[q] != 0;
7511 13775616 }
7512 53811 toggle_gswitches(states, true, screen_handles);
7513 53811 }
7514 14773158 void run_gswitch_timers()
7515 {
7516 14773158 bool states[256] = {false};
7517 14773158 auto& m = game->gswitch_timers.mut_inner();
7518
2/2
✓ Branch 0 taken 3777886208 times.
✓ Branch 1 taken 14773158 times.
3792659366 for(auto it = m.begin(); it != m.end();)
7519 {
7520
2/2
✓ Branch 0 taken 3777885608 times.
✓ Branch 1 taken 600 times.
3777886208 if(it->second > 0)
7521
2/2
✓ Branch 0 taken 599 times.
✓ Branch 1 taken 1 times.
600 if(!--it->second)
7522 {
7523 1 states[it->first] = true;
7524 1 it = m.erase(it);
7525 1 continue;
7526 }
7527 3777886207 ++it;
7528 }
7529 29935684 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7530 15162526 toggle_gswitches(states, false, create_screen_handles(scr));
7531 15162526 });
7532 14773158 }
7533 1122 void onload_gswitch_timers() //Reset all timers that were counting down, no trigger necessary
7534 {
7535
2/2
✓ Branch 0 taken 287232 times.
✓ Branch 1 taken 1122 times.
288354 for(auto q = 0; q < 256; ++q)
7536 {
7537
1/2
✓ Branch 0 taken 287232 times.
✗ Branch 1 not taken.
287232 if(game->gswitch_timers[q] > 0)
7538 game->gswitch_timers[q] = 0;
7539 287232 }
7540 1122 }
7541
7542 /**** View Map ****/
7543
7544 int32_t mapres = 0;
7545 int32_t view_map_show_mode = 3;
7546
7547 124544 bool displayOnMap(int32_t x, int32_t y)
7548 {
7549 124544 int32_t s = (y<<4) + x;
7550 124544 int mi = mapind(cur_map, s);
7551
2/2
✓ Branch 0 taken 67891 times.
✓ Branch 1 taken 56653 times.
124544 if (!(game->maps[mi]&mVISITED))
7552 67891 return false;
7553
7554 // Don't display if not part of DMap
7555
4/4
✓ Branch 0 taken 15628 times.
✓ Branch 1 taken 41025 times.
✓ Branch 2 taken 4655 times.
✓ Branch 3 taken 4311 times.
65619 if(((DMaps[cur_dmap].flags&dmfDMAPMAP) &&
7556
1/2
✓ Branch 0 taken 15628 times.
✗ Branch 1 not taken.
15628 (DMaps[cur_dmap].type != dmOVERW) &&
7557
2/2
✓ Branch 0 taken 12495 times.
✓ Branch 1 taken 3133 times.
15628 !(x >= DMaps[cur_dmap].xoff &&
7558
2/2
✓ Branch 0 taken 8966 times.
✓ Branch 1 taken 3529 times.
12495 x < DMaps[cur_dmap].xoff+8 &&
7559 8966 DMaps[cur_dmap].grid[y]&(128>>(x-DMaps[cur_dmap].xoff)))))
7560 10973 return false;
7561 else
7562 45680 return true;
7563 124544 }
7564
7565 973 void ViewMap()
7566 {
7567 973 ViewingMap = true;
7568
7569 973 BITMAP* mappic = NULL;
7570 static double scales[17] =
7571 {
7572 0.03125, 0.04419, 0.0625, 0.08839, 0.125, 0.177, 0.25, 0.3535,
7573 0.50, 0.707, 1.0, 1.414, 2.0, 2.828, 4.0, 5.657, 8.0
7574 };
7575
7576 973 int32_t px = ((8-(cur_screen&15)) << 9) - 256;
7577 973 int32_t py = ((4-(cur_screen>>4)) * 352) - 176;
7578 973 int32_t lx = ((cur_screen&15)<<8) + HeroX()+8;
7579 973 int32_t ly = ((cur_screen>>4)*176) + HeroY()+8;
7580 973 int32_t sc = 6;
7581
7582 973 bool done=false, redraw=true;
7583
7584 973 mappic = create_bitmap_ex(8,(256*16)>>mapres,(176*8)>>mapres);
7585
7586
1/2
✓ Branch 0 taken 973 times.
✗ Branch 1 not taken.
973 if(!mappic)
7587 {
7588 enter_sys_pal();
7589 jwin_alert("View Map","Not enough memory.",NULL,NULL,"OK",NULL,13,27,get_zc_font(font_lfont));
7590 exit_sys_pal();
7591 return;
7592 }
7593
7594 973 clear_to_color(mappic, WHITE);
7595
7596 973 auto prev_viewport = viewport;
7597 973 viewport.x = 0;
7598 973 viewport.y = 0;
7599
7600 // draw the map
7601 973 BITMAP* screen_bmp = create_bitmap_ex(8, 256, 176);
7602 973 combotile_add_x = 256;
7603 973 combotile_add_y = 0;
7604
2/2
✓ Branch 0 taken 7784 times.
✓ Branch 1 taken 973 times.
8757 for(int32_t y=0; y<8; y++)
7605 {
7606
2/2
✓ Branch 0 taken 124544 times.
✓ Branch 1 taken 7784 times.
132328 for(int32_t x=0; x<16; x++)
7607 {
7608
2/2
✓ Branch 0 taken 45680 times.
✓ Branch 1 taken 78864 times.
124544 if (!displayOnMap(x, y))
7609 78864 continue;
7610
7611 45680 int screen = map_scr_xy_to_index(x, y);
7612 45680 auto scrs = loadscr2(screen);
7613 45680 mapscr* scr = &scrs[0];
7614
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 if (!scr->is_valid())
7615 continue;
7616
7617 screen_handles_t screen_handles;
7618
2/2
✓ Branch 0 taken 45680 times.
✓ Branch 1 taken 319760 times.
365440 for (int i = 0; i <= 6; i++)
7619
3/4
✓ Branch 0 taken 319760 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103790 times.
✓ Branch 3 taken 215970 times.
319760 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
7620
7621 45680 int xx = 0;
7622 45680 int yy = -playing_field_offset;
7623
7624
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 45660 times.
45680 if(XOR(scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
7625 {
7626
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7627
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 do_ffc_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7628 20 }
7629
7630
2/2
✓ Branch 0 taken 175 times.
✓ Branch 1 taken 45505 times.
45680 if(XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
7631 {
7632
1/2
✓ Branch 0 taken 175 times.
✗ Branch 1 not taken.
175 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7633
1/2
✓ Branch 0 taken 175 times.
✗ Branch 1 not taken.
175 do_ffc_layer(screen_bmp, -3, screen_handles[0], xx, yy);
7634 175 }
7635
7636
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 if(lenscheck(scr,0)) putscr(scr, screen_bmp, 0, 0);
7637
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 0, screen_handles[0], xx, yy);
7638
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[1], xx, yy);
7639
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 1, screen_handles[0], xx, yy);
7640
7641
2/2
✓ Branch 0 taken 45660 times.
✓ Branch 1 taken 20 times.
45680 if(!XOR((scr->flags7&fLAYER2BG), DMaps[cur_dmap].flags&dmfLAYER2BG))
7642 {
7643
1/2
✓ Branch 0 taken 45660 times.
✗ Branch 1 not taken.
45660 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7644
1/2
✓ Branch 0 taken 45660 times.
✗ Branch 1 not taken.
45660 do_ffc_layer(screen_bmp, 2, screen_handles[0], xx, yy);
7645 45660 }
7646
7647
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 putscrdoors(scr, screen_bmp, xx, yy);
7648
2/2
✓ Branch 0 taken 41678 times.
✓ Branch 1 taken 4002 times.
45680 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
7649 {
7650
1/2
✓ Branch 0 taken 41678 times.
✗ Branch 1 not taken.
41678 do_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7651
2/2
✓ Branch 0 taken 1782 times.
✓ Branch 1 taken 39896 times.
41678 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
7652 {
7653
1/2
✓ Branch 0 taken 1782 times.
✗ Branch 1 not taken.
1782 do_layer(screen_bmp,-2, screen_handles[1], xx, yy);
7654
1/2
✓ Branch 0 taken 1782 times.
✗ Branch 1 not taken.
1782 do_layer(screen_bmp,-2, screen_handles[2], xx, yy);
7655 1782 }
7656 41678 }
7657
7658
2/2
✓ Branch 0 taken 45505 times.
✓ Branch 1 taken 175 times.
45680 if(!XOR((scr->flags7&fLAYER3BG), DMaps[cur_dmap].flags&dmfLAYER3BG))
7659 {
7660
1/2
✓ Branch 0 taken 45505 times.
✗ Branch 1 not taken.
45505 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7661
1/2
✓ Branch 0 taken 45505 times.
✗ Branch 1 not taken.
45505 do_ffc_layer(screen_bmp, 3, screen_handles[0], xx, yy);
7662 45505 }
7663
7664
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[4], xx, yy);
7665
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 4, screen_handles[0], xx, yy);
7666
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7667
2/2
✓ Branch 0 taken 5784 times.
✓ Branch 1 taken 39896 times.
45680 if(get_qr(qr_OVERHEAD_COMBOS_L1_L2))
7668 {
7669
1/2
✓ Branch 0 taken 5784 times.
✗ Branch 1 not taken.
5784 do_layer(screen_bmp,-1, screen_handles[1], xx, yy);
7670
1/2
✓ Branch 0 taken 5784 times.
✗ Branch 1 not taken.
5784 do_layer(screen_bmp,-1, screen_handles[2], xx, yy);
7671 5784 }
7672
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[5], xx, yy);
7673
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 5, screen_handles[0], xx, yy);
7674
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 45680 times.
45680 if(replay_version_check(40))
7675 do_ffc_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7676
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[6], xx, yy);
7677
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 6, screen_handles[0], xx, yy);
7678
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 7, screen_handles[0], xx, yy);
7679
7680
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 stretch_blit(screen_bmp, mappic, 0, 0, 256, 176, x<<(8-mapres), (y*176)>>mapres, 256>>mapres, 176>>mapres);
7681
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
45680 }
7682 7784 }
7683
7684 973 viewport = prev_viewport;
7685 973 combotile_add_x = 0;
7686 973 combotile_add_y = 0;
7687
7688 973 destroy_bitmap(screen_bmp);
7689 973 clear_keybuf();
7690 973 pause_all_sfx();
7691
7692 // view it
7693 973 int32_t delay = 0;
7694
7695 973 do
7696 {
7697
2/2
✓ Branch 0 taken 178717 times.
✓ Branch 1 taken 29891 times.
208608 if (replay_version_check(0, 11))
7698 29891 load_control_state();
7699
7700 208608 int32_t step = int32_t(16.0/scales[sc]);
7701 208608 step = (step>>1) + (step&1);
7702 208608 bool r = cRbtn();
7703
7704
1/2
✓ Branch 0 taken 208608 times.
✗ Branch 1 not taken.
208608 if(cLbtn())
7705 {
7706 step <<= 2;
7707 delay = 0;
7708 }
7709
7710
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 208608 times.
208608 if(r)
7711 {
7712 if(rUp())
7713 {
7714 py+=step;
7715 redraw=true;
7716 }
7717
7718 if(rDown())
7719 {
7720 py-=step;
7721 redraw=true;
7722 }
7723
7724 if(rLeft())
7725 {
7726 px+=step;
7727 redraw=true;
7728 }
7729
7730 if(rRight())
7731 {
7732 px-=step;
7733 redraw=true;
7734 }
7735 }
7736 else
7737 {
7738
2/2
✓ Branch 0 taken 193729 times.
✓ Branch 1 taken 14879 times.
208608 if(Up())
7739 {
7740 14879 py+=step;
7741 14879 redraw=true;
7742 14879 }
7743
7744
2/2
✓ Branch 0 taken 193574 times.
✓ Branch 1 taken 15034 times.
208608 if(Down())
7745 {
7746 15034 py-=step;
7747 15034 redraw=true;
7748 15034 }
7749
7750
2/2
✓ Branch 0 taken 182159 times.
✓ Branch 1 taken 26449 times.
208608 if(Left())
7751 {
7752 26449 px+=step;
7753 26449 redraw=true;
7754 26449 }
7755
7756
2/2
✓ Branch 0 taken 182774 times.
✓ Branch 1 taken 25834 times.
208608 if(Right())
7757 {
7758 25834 px-=step;
7759 25834 redraw=true;
7760 25834 }
7761 }
7762
7763
2/2
✓ Branch 0 taken 187444 times.
✓ Branch 1 taken 21164 times.
208608 if(delay)
7764 21164 --delay;
7765 else
7766 {
7767 187444 bool a = cAbtn();
7768 187444 bool b = cBbtn();
7769
7770
3/4
✓ Branch 0 taken 1721 times.
✓ Branch 1 taken 185723 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1721 times.
187444 if(a && !b)
7771 {
7772
1/2
✓ Branch 0 taken 1721 times.
✗ Branch 1 not taken.
1721 sc=zc_min(sc+1,16);
7773 1721 delay=8;
7774 1721 redraw=true;
7775 1721 }
7776
7777
3/4
✓ Branch 0 taken 927 times.
✓ Branch 1 taken 186517 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 927 times.
187444 if(b && !a)
7778 {
7779
2/2
✓ Branch 0 taken 926 times.
✓ Branch 1 taken 1 times.
927 sc=zc_max(sc-1,0);
7780 927 delay=8;
7781 927 redraw=true;
7782 927 }
7783 }
7784
7785
2/2
✓ Branch 0 taken 208597 times.
✓ Branch 1 taken 11 times.
208608 if(rPbtn())
7786 11 --view_map_show_mode;
7787
7788 208608 px = vbound(px,-4096,4096);
7789 208608 py = vbound(py,-1408,1408);
7790
7791 208608 double scale = scales[sc];
7792
7793
2/2
✓ Branch 0 taken 72838 times.
✓ Branch 1 taken 135770 times.
208608 if(!redraw)
7794 {
7795 135770 blit(scrollbuf_old,framebuf,256,0,0,0,256,232);
7796 135770 }
7797 else
7798 {
7799 72838 clear_to_color(framebuf,BLACK);
7800 145676 stretch_blit(mappic,framebuf,0,0,mappic->w,mappic->h,
7801 72838 int32_t(256+(int64_t(px)-mappic->w)*scale)/2,int32_t(224+(int64_t(py)-mappic->h)*scale)/2,
7802 72838 int32_t(mappic->w*scale),int32_t(mappic->h*scale));
7803
7804 72838 blit(framebuf,scrollbuf_old,0,0,256,0,256,232);
7805 72838 redraw=false;
7806 }
7807
7808 208608 int32_t x = int32_t(256+(px-((2048-int64_t(lx))*2))*scale)/2;
7809 208608 int32_t y = int32_t(224+(py-((704-int64_t(ly))*2))*scale)/2;
7810
7811
2/2
✓ Branch 0 taken 7466 times.
✓ Branch 1 taken 201142 times.
208608 if(view_map_show_mode&1)
7812 {
7813 201142 line(framebuf,x-7,y-7,x+7,y+7,(frame&3)+252);
7814 201142 line(framebuf,x+7,y-7,x-7,y+7,(frame&3)+252);
7815 201142 }
7816
7817
3/4
✓ Branch 0 taken 5600 times.
✓ Branch 1 taken 203008 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5600 times.
208608 if(view_map_show_mode&2 || r)
7818 203008 textprintf_ex(framebuf,font,224,216,WHITE,BLACK,"%1.2f",scale);
7819
7820
1/2
✓ Branch 0 taken 208608 times.
✗ Branch 1 not taken.
208608 if(r)
7821 {
7822 textprintf_ex(framebuf,font,0,208,WHITE,BLACK,"m: %d %d",px,py);
7823 textprintf_ex(framebuf,font,0,216,WHITE,BLACK,"x: %d %d",x,y);
7824 }
7825
7826 208608 advanceframe(false, false);
7827
2/2
✓ Branch 0 taken 29891 times.
✓ Branch 1 taken 178717 times.
208608 if (replay_version_check(11))
7828 178717 load_control_state();
7829
7830
2/2
✓ Branch 0 taken 207636 times.
✓ Branch 1 taken 972 times.
208608 if(getInput(btnS, true, false, true)) //rSbtn
7831 972 done = true;
7832
7833
2/2
✓ Branch 0 taken 973 times.
✓ Branch 1 taken 207635 times.
417216 }
7834
2/2
✓ Branch 0 taken 972 times.
✓ Branch 1 taken 207636 times.
208608 while(!done && !Quit);
7835
7836 973 ViewingMap = false;
7837 973 destroy_bitmap(mappic);
7838 973 resume_all_sfx();
7839 973 }
7840
7841 1075 int32_t onViewMap()
7842 {
7843
4/6
✓ Branch 0 taken 1075 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1075 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 102 times.
✓ Branch 5 taken 973 times.
1075 if(Playing && cur_screen<128 && DMaps[cur_dmap].flags&dmfVIEWMAP)
7844 {
7845 973 clear_to_color(framebuf,BLACK);
7846 973 textout_centre_ex(framebuf,font,"Drawing map...",128,108,WHITE,BLACK);
7847 973 advanceframe(true);
7848 973 ViewMap();
7849 973 }
7850
7851 1075 return D_O_K;
7852 }
7853
7854 35757391 bool isGrassType(int32_t type)
7855 {
7856
2/2
✓ Branch 0 taken 35080979 times.
✓ Branch 1 taken 676412 times.
35757391 switch(type)
7857 {
7858 case cTALLGRASS:
7859 case cTALLGRASSNEXT:
7860 case cTALLGRASSTOUCHY:
7861 676412 return true;
7862 }
7863
7864 35080979 return false;
7865 35757391 }
7866
7867 20914 bool isFlowersType(int32_t type)
7868 {
7869
2/2
✓ Branch 0 taken 16574 times.
✓ Branch 1 taken 4340 times.
20914 switch(type)
7870 {
7871 case cFLOWERS:
7872 case cFLOWERSTOUCHY:
7873 4340 return true;
7874 }
7875
7876 16574 return false;
7877 20914 }
7878
7879 bool isGenericType(int32_t type)
7880 {
7881 switch(type)
7882 {
7883 case cTRIGGERGENERIC:
7884 return true;
7885 }
7886
7887 return false;
7888 }
7889
7890 26056 bool isBushType(int32_t type)
7891 {
7892
2/2
✓ Branch 0 taken 20914 times.
✓ Branch 1 taken 5142 times.
26056 switch(type)
7893 {
7894 case cBUSH:
7895 case cBUSHNEXT:
7896 case cBUSHTOUCHY:
7897 case cBUSHNEXTTOUCHY:
7898
7899 5142 return true;
7900 }
7901
7902 20914 return false;
7903 26056 }
7904
7905 bool isSlashType(int32_t type)
7906 {
7907 switch(type)
7908 {
7909 case cSLASH:
7910 case cSLASHITEM:
7911 case cSLASHTOUCHY:
7912 case cSLASHITEMTOUCHY:
7913 case cSLASHNEXT:
7914 case cSLASHNEXTITEM:
7915 case cSLASHNEXTTOUCHY:
7916 case cSLASHNEXTITEMTOUCHY:
7917 return true;
7918 }
7919
7920 return false;
7921 }
7922
7923 15695 bool isCuttableNextType(int32_t type)
7924 {
7925
2/2
✓ Branch 0 taken 9788 times.
✓ Branch 1 taken 5907 times.
15695 switch(type)
7926 {
7927 case cSLASHNEXT:
7928 case cSLASHNEXTITEM:
7929 case cTALLGRASSNEXT:
7930 case cBUSHNEXT:
7931 case cSLASHNEXTTOUCHY:
7932 case cSLASHNEXTITEMTOUCHY:
7933 case cBUSHNEXTTOUCHY:
7934 5907 return true;
7935 }
7936
7937 9788 return false;
7938 15695 }
7939
7940 17546 bool isTouchyType(int32_t type)
7941 {
7942
2/2
✓ Branch 0 taken 6050 times.
✓ Branch 1 taken 11496 times.
17546 switch(type)
7943 {
7944 case cSLASHTOUCHY:
7945 case cSLASHITEMTOUCHY:
7946 case cBUSHTOUCHY:
7947 case cFLOWERSTOUCHY:
7948 case cTALLGRASSTOUCHY:
7949 case cSLASHNEXTTOUCHY:
7950 case cSLASHNEXTITEMTOUCHY:
7951 case cBUSHNEXTTOUCHY:
7952 11496 return true;
7953 }
7954
7955 6050 return false;
7956 17546 }
7957
7958 29332374 bool isCuttableType(int32_t type)
7959 {
7960
2/2
✓ Branch 0 taken 28883109 times.
✓ Branch 1 taken 449265 times.
29332374 switch(type)
7961 {
7962 case cSLASH:
7963 case cSLASHITEM:
7964 case cBUSH:
7965 case cFLOWERS:
7966 case cTALLGRASS:
7967 case cTALLGRASSNEXT:
7968 case cSLASHNEXT:
7969 case cSLASHNEXTITEM:
7970 case cBUSHNEXT:
7971
7972 case cSLASHTOUCHY:
7973 case cSLASHITEMTOUCHY:
7974 case cBUSHTOUCHY:
7975 case cFLOWERSTOUCHY:
7976 case cTALLGRASSTOUCHY:
7977 case cSLASHNEXTTOUCHY:
7978 case cSLASHNEXTITEMTOUCHY:
7979 case cBUSHNEXTTOUCHY:
7980 449265 return true;
7981 }
7982
7983 28883109 return false;
7984 29332374 }
7985
7986 17322 bool isCuttableItemType(int32_t type)
7987 {
7988
2/2
✓ Branch 0 taken 424 times.
✓ Branch 1 taken 16898 times.
17322 switch(type)
7989 {
7990 case cSLASHITEM:
7991 case cBUSH:
7992 case cFLOWERS:
7993 case cTALLGRASS:
7994 case cTALLGRASSNEXT:
7995 case cSLASHNEXTITEM:
7996 case cBUSHNEXT:
7997
7998 case cSLASHITEMTOUCHY:
7999 case cBUSHTOUCHY:
8000 case cFLOWERSTOUCHY:
8001 case cTALLGRASSTOUCHY:
8002 case cSLASHNEXTITEMTOUCHY:
8003 case cBUSHNEXTTOUCHY:
8004 16898 return true;
8005 }
8006
8007 424 return false;
8008 17322 }
8009
8010 66 bool is_push(mapscr* m, int32_t pos)
8011 {
8012
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 if(is_push_flag(m->sflag[pos]))
8013 return true;
8014 66 newcombo const& cmb = combobuf[m->data[pos]];
8015
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 if(is_push_flag(cmb.flag))
8016 return true;
8017
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 52 times.
66 if(cmb.type == cPUSHBLOCK)
8018 14 return true;
8019
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
52 if(cmb.type == cSWITCHHOOK && (cmb.usrflags&cflag7))
8020 return true; //Counts as 'pushblock' flag
8021 52 return false;
8022 66 }
8023
8024 416 static std::map<int, screen_state_t> screen_states;
8025
8026 35860 std::map<int, screen_state_t>& get_screen_states()
8027 {
8028 35860 return screen_states;
8029 }
8030
8031 44182917 screen_state_t& get_screen_state(int screen)
8032 {
8033 44182917 return screen_states[screen];
8034 }
8035
8036 581 void clear_screen_states()
8037 {
8038 581 screen_states.clear();
8039 581 }
8040
8041 1439 void screen_item_set_state(int screen, ScreenItemState state)
8042 {
8043 1439 get_screen_state(screen).item_state = state;
8044 1439 }
8045
8046 37023 void mark_visited(int screen)
8047 {
8048
2/2
✓ Branch 0 taken 475 times.
✓ Branch 1 taken 36548 times.
37023 if (screen < 0x80)
8049 {
8050
2/2
✓ Branch 0 taken 24616 times.
✓ Branch 1 taken 11932 times.
36548 if(DMaps[cur_dmap].flags&dmfVIEWMAP)
8051 11932 game->maps[mapind(cur_map, screen)] |= mVISITED;
8052
8053 36548 markBmap(-1, screen);
8054 36548 }
8055 37023 }
8056